[Phpfreechat-svn] SF.net SVN: phpfreechat: [677] trunk/src
Status: Beta
Brought to you by:
kerphi
From: <ke...@us...> - 2006-08-17 21:10:38
|
Revision: 677 Author: kerphi Date: 2006-08-17 14:10:14 -0700 (Thu, 17 Aug 2006) ViewCVS: http://svn.sourceforge.net/phpfreechat/?rev=677&view=rev Log Message: ----------- # Big refactoring: * Set the prefix parameter value to "pfc_". Now this parameter can't be changed because it simplify the new developments. * Change the manner how resources are manager. Resources were copied into a public directory. Now resources are just delivered by the proxy.php file which is placed into the publix directory. * Remove php code into each resources files (javascript, css). So now the chat page size is lighter from -50% (80ko to 30ko). * No more chat-post.js.tpl.php, chat-pre.js.tpl.php, and pfcclient-custo.js.tpl.php. All these redundant files are now merged into one unique file : customize.js. * The chat is now generated by Javascript routines. # Redesign the default skin (it's nicer for me, maybe for you too ?). Modified Paths: -------------- trunk/demo/demo15_multiple_channel.php trunk/src/commands/nick.class.php trunk/src/pfcglobalconfig.class.php trunk/src/pfcuserconfig.class.php trunk/src/phpfreechat.class.php trunk/themes/default/images/oldmsg.gif Added Paths: ----------- trunk/demo/demo5_customized_style_data/mytheme/style.css trunk/src/client/ trunk/src/client/chat.js.tpl.php trunk/src/client/pfcclient.js trunk/src/client/pfcgui.js trunk/src/client/pfcresource.js trunk/src/client/proxy.php.tpl trunk/themes/default/customize.js trunk/themes/default/images/background.gif trunk/themes/default/images/newmsg.gif trunk/themes/default/style.css Removed Paths: ------------- trunk/demo/demo5_customized_style_data/mytheme/templates/ trunk/themes/default/images/shade.gif trunk/themes/default/templates/ Modified: trunk/demo/demo15_multiple_channel.php =================================================================== --- trunk/demo/demo15_multiple_channel.php 2006-08-17 17:55:00 UTC (rev 676) +++ trunk/demo/demo15_multiple_channel.php 2006-08-17 21:10:14 UTC (rev 677) @@ -5,7 +5,7 @@ $params["serverid"] = md5(__FILE__); // calculate a unique id for this chat $params["title"] = "A simple chat with multiple/dynamic channels (rooms)"; $params["nick"] = "guest"; // setup the intitial nickname -$params["channel"] = isset($_GET["channel"]) ? $_GET["channel"] : "room1"; +//$params["channel"] = isset($_GET["channel"]) ? $_GET["channel"] : "room1"; $chat = new phpFreeChat( $params ); ?> @@ -23,14 +23,10 @@ <body> <p>Rooms list:</p> <ul> - <li><a href="?channel=room1">#room1</a></li> - <li><a href="?channel=room2">#room2</a></li> + <li><a href="#" onclick="pfc.sendRequest('/join', 'room1');">room1</a></li> + <li><a href="#" onclick="pfc.sendRequest('/join', 'room2');">room2</a></li> </ul> -<?php - $c =& pfcGlobalConfig::Instance(); - echo "<p>You are in #".$c->channel."</p>"; -?> <?php $chat->printChat(); ?> <?php Added: trunk/demo/demo5_customized_style_data/mytheme/style.css =================================================================== --- trunk/demo/demo5_customized_style_data/mytheme/style.css (rev 0) +++ trunk/demo/demo5_customized_style_data/mytheme/style.css 2006-08-17 21:10:14 UTC (rev 677) @@ -0,0 +1,66 @@ + +div#pfc_container { + border: black double 5px; + background-image: url("proxy.php?p=mytheme/images/brick.jpg"); + background-repeat: repeat; + padding: 20px; + color: black; + margin: auto; +} +div#pfc_chat { + background-color: #FFF; +} + +div#pfc_content { + border: none; +} + +div.pfc_message { + background-color: transparent; + background-image: url("proxy.php?p=mytheme/images/newmsg.gif"); + background-repeat: no-repeat; + background-position: right center; +} + +div.pfc_oldmsg { + background-image: url("proxy.php?p=mytheme/images/oldmsg.gif"); +} + +span.pfc_heure { + margin-left: 25px; + color: #888; +} + +span.pfc_date { + display: none; +} + +span.pfc_pseudo { + color: black; + font-weight: bold; +} + +input#pfc_handle { + color: black; + font-weight: bold; +} + +div#pfc_online { +} + +div.pfc_btn img { + border: 1px solid #FFF; /* same as container color */ +} +div.pfc_btn img:hover { + border: 1px solid #000; + background-color: #CCC; +} + + +/* commands */ +.pfc_cmd_notice { + color: red; +} +.pfc_cmd_msg { + color: #555; +} \ No newline at end of file Added: trunk/src/client/chat.js.tpl.php =================================================================== --- trunk/src/client/chat.js.tpl.php (rev 0) +++ trunk/src/client/chat.js.tpl.php 2006-08-17 21:10:14 UTC (rev 677) @@ -0,0 +1,149 @@ +var pfc_nickname = '<?php echo addslashes($u->nick); ?>'; +var pfc_clientid = '<?php echo md5(uniqid(rand(), true)); ?>'; +var pfc_title = '<?php echo addslashes($title); ?>'; +var pfc_refresh_delay = <?php echo $refresh_delay; ?>; +var pfc_start_minimized = <?php echo $start_minimized ? "true" : "false"; ?>; +var pfc_nickmarker = <?php echo $nickmarker ? "true" : "false"; ?>; +var pfc_clock = <?php echo $clock ? "true" : "false"; ?>; +var pfc_showsmileys = <?php echo $showsmileys ? "true" : "false"; ?>; +var pfc_showwhosonline = <?php echo $showwhosonline ? "true" : "false"; ?>; +var pfc_focus_on_connect = <?php echo $focus_on_connect ? "true" : "false"; ?>; +var pfc_max_text_len = <?php echo $max_text_len; ?>; +var pfc_quit_on_closedwindow = <?php echo $quit_on_closedwindow ? "true" : "false"; ?>; +var pfc_debug = <?php echo $debug ? "true" : "false"; ?>; +var pfc_max_text_len = <?php echo $max_text_len; ?>; +var pfc_btn_sh_smileys = <?php echo $btn_sh_smileys ? "true" : "false"; ?>; +var pfc_btn_sh_whosonline = <?php echo $btn_sh_whosonline ? "true" : "false"; ?>; +var pfc_connect_at_startup = <?php echo $connect_at_startup ? "true" : "false"; ?>; +var pfc_defaultchan = Array(<?php + function quoteandescape($v) { return "'".addslashes($v)."'"; } + $list = array(); foreach($c->channels as $ch) {$list[] = $ch; } + $list = array_map("quoteandescape",$list); + echo implode(",", $list); + ?>); +var pfc_userchan = Array(<?php + $list = array(); foreach($u->channels as $ch) {$list[] = $ch["name"];} + $list = array_map("quoteandescape",$list); + echo implode(",", $list); + ?>); +var pfc_privmsg = Array(<?php + $list = array(); foreach($u->privmsg as $pv) {$list[] = $pv["name"];} + $list = array_map("quoteandescape",$list); + echo implode(",", $list); + ?>); +var pfc_openlinknewwindow = <?php echo $openlinknewwindow ? "true" : "false"; ?>; +<?php +$bbcode_clist = array("FFFFFF","000000","000055","008000","FF0000","800000","800080","FF5500","FFFF00","00FF00","008080","00FFFF","0000FF","FF00FF","7F7F7F","D2D2D2"); +?> +var pfc_bbcode_color_list = Array(<?php + $list = array(); foreach($bbcode_clist as $v) {$list[] = $v;} + $list = array_map("quoteandescape",$list); + echo implode(",", $list); + ?>); +<?php +$nickname_clist = array('#CCCCCC','#000000','#3636B2','#2A8C2A','#C33B3B','#C73232','#80267F','#66361F','#D9A641','#3DCC3D','#1A5555','#2F8C74','#4545E6','#B037B0','#4C4C4C','#959595'); +?> +var pfc_nickname_color_list = Array(<?php + $list = array(); foreach($nickname_clist as $v) {$list[] = $v;} + $list = array_map("quoteandescape",$list); + echo implode(",", $list); + ?>); +var pfc_proxy_url = '<?php echo $data_public_url."/".$serverid."/proxy.php"; ?>'; + + +/* create our client which will do all the work on the client side ! */ +var pfc = new pfcClient(); +<?php + +$labels_to_load = +array( "Do you really want to leave this room ?", + "Hide nickname marker", + "Show nickname marker", + "Hide dates and hours", + "Show dates and hours", + "Disconnect", + "Connect", + "Magnify", + "Cut down", + "Hide smiley box", + "Show smiley box", + "Hide online users box", + "Show online users box", + "Please enter your nickname", + "Private message", + "Close this tab", + "Enter your message here", + "Enter your nickname here", + "Bold", + "Italics", + "Underline", + "Delete", + "Mail", + "Color", + ); +foreach($labels_to_load as $l) +{ + echo "pfc.res.setLabel('".$l."','".addslashes(_pfc($l))."');\n"; +} + +$fileurl_to_load = +array( 'images/ch.gif', + 'images/pv.gif', + 'images/tab_remove.gif', + 'images/ch-active.gif', + 'images/pv-active.gif', + 'images/user.gif', + 'images/user-me.gif', + 'images/color-on.gif', + 'images/color-off.gif', + 'images/clock-on.gif', + 'images/clock-off.gif', + 'images/logout.gif', + 'images/login.gif', + 'images/maximize.gif', + 'images/minimize.gif', + 'images/smiley-on.gif', + 'images/smiley-off.gif', + 'images/online-on.gif', + 'images/online-off.gif', + 'images/bt_strong.gif', + 'images/bt_em.gif', + 'images/bt_ins.gif', + 'images/bt_del.gif', + 'images/bt_mail.gif', + 'images/bt_color.gif', + ); + +// convert bbcode color value list to a bbcode color url list +function get_bbcode_color_url($v) { return 'images/color_'.$v.'.gif'; } +$bbcode_clist = array_map("get_bbcode_color_url",$bbcode_clist); + +$fileurl_to_load = array_merge($fileurl_to_load, $bbcode_clist); +foreach($fileurl_to_load as $f) +{ + echo "pfc.res.setFileUrl('".$f."',pfc_proxy_url+'".$c->getFileUrlByProxy($f,false)."');\n"; +} + +foreach($smileys as $s_file => $s_str) { + for($j = 0; $j<count($s_str) ; $j++) { + echo "pfc.res.setSmiley('".$s_str[$j]."',pfc_proxy_url+'".$c->getFileUrlByProxy($s_file,false)."');\n"; + } +} + +?> + +pfc.gui.buildChat(); +pfc.connectListener(); +pfc.refreshGUI(); +if (pfc_connect_at_startup) pfc.connect_disconnect(); + +<?php if ($debugxajax) { ?> +xajax.DebugMessage = function(text) +{ + var s = new String(text); + text = s.escapeHTML(); + rx = new RegExp('<','g'); + text = text.replace(rx, '\n<'); + $('debugxajax').innerHTML += '\n---------------\n' + text; +} +<?php } ?> Added: trunk/src/client/pfcclient.js =================================================================== --- trunk/src/client/pfcclient.js (rev 0) +++ trunk/src/client/pfcclient.js 2006-08-17 21:10:14 UTC (rev 677) @@ -0,0 +1,1367 @@ +var is_ie = navigator.appName.match("Explorer"); +var is_khtml = navigator.appName.match("Konqueror") || navigator.appVersion.match("KHTML"); +var is_ff = navigator.appName.match("Netscape"); + +/** + * This class is the client part of phpFreeChat + * (depends on prototype library) + * @author Stephane Gully + */ +var pfcClient = Class.create(); + +//defining the rest of the class implmentation +pfcClient.prototype = { + + initialize: function() + { + // load the graphical user interface builder + this.gui = new pfcGui(); + // load the resources manager (labels and urls) + this.res = new pfcResource(); + + this.nickname = pfc_nickname; + + // this array contains all the sent command + // used the up and down key to navigate in the history + // (doesn't work on IE6) + this.cmdhistory = Array(); + this.cmdhistoryid = -1; + this.cmdhistoryissearching = false; + + /* + this.channels = Array(); + this.channelids = Array(); + */ + this.privmsgs = Array(); + this.privmsgids = Array(); + + this.timeout = null; + this.refresh_delay = pfc_refresh_delay; + /* unique client id for each windows used to identify a open window + * this id is passed every time the JS communicate with server + * (2 clients can use the same session: then only the nickname is shared) */ + this.clientid = pfc_clientid; + + this.isconnected = false; + this.nicklist = $H(); + this.nickcolor = Array(); + this.colorlist = Array(); + + this.blinktmp = Array(); + this.blinkloop = Array(); + this.blinktimeout = Array(); + + }, + + connectListener: function() + { + this.el_words = $('pfc_words'); + this.el_handle = $('pfc_handle'); + this.el_container = $('pfc_container'); + this.el_online = $('pfc_online'); + this.el_errors = $('pfc_errors'); + + /* the events callbacks */ + this.el_words.onkeypress = this.callbackWords_OnKeypress.bindAsEventListener(this); + this.el_words.onkeydown = this.callbackWords_OnKeydown.bindAsEventListener(this); + this.el_words.onfocus = this.callbackWords_OnFocus.bindAsEventListener(this); + this.el_handle.onkeydown = this.callbackHandle_OnKeydown.bindAsEventListener(this); + this.el_handle.onchange = this.callbackHandle_OnChange.bindAsEventListener(this); + this.el_container.onmousemove = this.callbackContainer_OnMousemove.bindAsEventListener(this); + this.el_container.onmousedown = this.callbackContainer_OnMousedown.bindAsEventListener(this); + this.el_container.onmouseup = this.callbackContainer_OnMouseup.bindAsEventListener(this); + document.body.onunload = this.callback_OnUnload.bindAsEventListener(this); + }, + + refreshGUI: function() + { + this.minmax_status = pfc_start_minimized; + var cookie = getCookie('pfc_minmax_status'); + if (cookie != null) + this.minmax_status = (cookie == 'true'); + + cookie = getCookie('pfc_nickmarker'); + this.nickmarker = (cookie == 'true'); + if (cookie == '' || cookie == null) + this.nickmarker = pfc_nickmarker; + + cookie = getCookie('pfc_clock'); + this.clock = (cookie == 'true'); + if (cookie == '' || cookie == null) + this.clock = pfc_clock; + + cookie = getCookie('pfc_showsmileys'); + this.showsmileys = (cookie == 'true'); + if (cookie == '' || cookie == null) + this.showsmileys = pfc_showsmileys; + + cookie = getCookie('pfc_showwhosonline'); + this.showwhosonline = (cookie == 'true'); + if (cookie == '' || cookie == null) + this.showwhosonline = pfc_showwhosonline; + + // '' means no forced color, let CSS choose the text color + this.current_text_color = ''; + cookie = getCookie('pfc_current_text_color'); + if (cookie != null) + this.switch_text_color(cookie); + + this.refresh_loginlogout(); + this.refresh_minimize_maximize(); + this.refresh_Smileys(); + this.refresh_nickmarker(); + }, + + /** + * Show a popup dialog to ask user to choose a nickname + */ + askNick: function(nickname) + { + // ask to choose a nickname + if (nickname == '') nickname = this.nickname; + var newnick = prompt(this.res.getLabel('Please enter your nickname'), nickname); + if (newnick) + this.sendRequest('/nick', newnick); + }, + + /** + * Reacte to the server response + */ + handleResponse: function(cmd, resp, param) + { + if (cmd == "connect") + { + //alert(cmd + "-"+resp+"-"+param); + if (resp == "ok") + { + if (this.nickname == '') + // ask to choose a nickname + this.askNick(this.nickname); + else + { + this.sendRequest('/nick', this.nickname); + } + + // give focus the the input text box if wanted + if (pfc_focus_on_connect) this.el_words.focus(); + + this.isconnected = true; + + // start the polling system + this.updateChat(true); + } + else + this.isconnected = false; + this.refresh_loginlogout(); + } + else if (cmd == "quit") + { + if (resp =="ok") + { + // stop updates + this.updateChat(false); + this.isconnected = false; + this.refresh_loginlogout(); + } + } + else if (cmd == "join") + { + if (resp =="ok") + { + // create the new channel + var tabid = param[0]; + var name = param[1]; + this.gui.createTab(name, tabid, "ch"); + this.gui.setTabById(tabid); + /* + this.channels.push(name); + this.channelids.push(tabid); + */ + this.refresh_Smileys(); + this.refresh_WhosOnline(); + } + else + alert(cmd + "-"+resp+"-"+param); + } + else if (cmd == "join2") + { + if (resp =="ok") + { + // create the new channel + var tabid = param[0]; + var name = param[1]; + this.gui.createTab(name, tabid, "ch"); + // do not switch to the new created tab + // keep it in the background + // this.gui.setTabById(tabid); + this.refresh_WhosOnline(); + } + else + alert(cmd + "-"+resp+"-"+param); + } + else if (cmd == "leave") + { + //alert(cmd + "-"+resp+"-"+param); + if (resp =="ok") + { + // remove the channel + var tabid = param; + this.gui.removeTabById(tabid); + + // synchronize the channel client arrays + /* + var index = -1; + index = this.channelids.indexOf(tabid); + this.channelids = this.channelids.without(tabid); + this.channels = this.channels.without(this.channels[index]); + */ + + // synchronize the privmsg client arrays + index = -1; + index = indexOf(this.privmsgids, tabid); + this.privmsgids = without(this.privmsgids, tabid); + this.privmsgs = without(this.privmsgs, this.privmsgs[index]); + + } + } + else if (cmd == "privmsg") + { + if (resp == "ok") + { + // create the new channel + var tabid = param[0]; + var name = param[1]; + this.gui.createTab(name, tabid, "pv"); + this.gui.setTabById(tabid); + + this.privmsgs.push(name); + this.privmsgids.push(tabid); + + } + else if (resp == "unknown") + { + // speak to unknown user + } + else + alert(cmd + "-"+resp+"-"+param); + } + else if (cmd == "privmsg2") + { + if (resp == "ok") + { + // create the new channel + var tabid = param[0]; + var name = param[1]; + this.gui.createTab(name, tabid, "pv"); + // do not switch to the new created tab + // keep it in the background + // this.gui.setTabById(tabid); + + this.privmsgs.push(name); + this.privmsgids.push(tabid); + } + else if (resp == "unknown") + { + // speak to unknown user + } + else + alert(cmd + "-"+resp+"-"+param); + } + else if (cmd == "nick") + { + if (resp == "connected" || resp == "notchanged") + { + // now join channels comming from sessions + // or the default one + cmd = ''; + if (pfc_userchan.length == 0) + { + for (var i=0; i<pfc_defaultchan.length; i++) + { + if (i<pfc_defaultchan.length-1) + cmd = "/join2"; + else + cmd = "/join"; + this.sendRequest(cmd, pfc_defaultchan[i]); + } + } + for (var i=0; i<pfc_userchan.length; i++) + { + if (i<pfc_userchan.length-1) + cmd = "/join2"; + else + cmd = "/join"; + this.sendRequest(cmd, pfc_userchan[i]); + } + for (var i=0; i<pfc_privmsg.length; i++) + { + this.sendRequest("/privmsg", pfc_privmsg[i]); + } + } + + if (resp == "ok" || resp == "notchanged" || resp == "changed" || resp == "connected") + { + this.el_handle.value = param; + this.nickname = param; + } + else if (resp == "isused") + { + this.askNick(param); + } + else + alert(cmd + "-"+resp+"-"+param); + } + else if (cmd == "update") + { + if (resp == "ok") + { + } + } + else if (cmd == "rehash") + { + if (resp == "ok") + { + this.displayMsg( cmd, this.res.getLabel('Configuration has been rehashed') ); + } + else if (resp == "ko") + { + this.displayMsg( cmd, this.res.getLabel('A problem occurs during rehash') ); + } + } + else if (cmd == "banlist") + { + if (resp == "ok" || resp == "ko") + { + this.displayMsg( cmd, param ); + } + } + else if (cmd == "unban") + { + if (resp == "ok" || resp == "ko") + { + this.displayMsg( cmd, param ); + } + } + else if (cmd == "auth") + { + if (resp == "ban") + { + alert(param); + } + if (resp == "frozen") + { + alert(param); + } + else if (resp == "nick") + { + this.displayMsg( cmd, param ); + } + } + else if (cmd == "debug") + { + if (resp == "ok" || resp == "ko") + { + this.displayMsg( cmd, param ); + } + } + else if (cmd == "clear") + { + var tabid = this.gui.getTabId(); + var container = this.gui.getChatContentFromTabId(tabid); + container.innerHTML = ""; + } + else if (cmd == "identify") + { + this.displayMsg( cmd, param ); + } + else + alert(cmd + "-"+resp+"-"+param); + }, + + /** + * Try to complete a nickname like on IRC when pressing the TAB key + * @todo: improve the algorithme, it should take into account the cursor position + */ + completeNick: function() + { + var w = this.el_words; + var nick_src = w.value.substring(w.value.lastIndexOf(' ')+1,w.value.length); + if (nick_src != '') + { + var ul_online = this.el_online.firstChild; + for (var i=0; i<ul_online.childNodes.length; i++) + { + var nick = ul_online.childNodes[i].innerHTML; + if (indexOf(nick, nick_src) == 0) + w.value = w.value.replace(nick_src, nick); + } + } + }, + + /** + * Handle the pressed keys + * see also callbackWords_OnKeydown + */ + callbackWords_OnKeypress: function(evt) + { + var code = (evt.which) ? evt.which : evt.keyCode; + if (code == Event.KEY_TAB) /* tab key */ + { + /* FF & Konqueror workaround : ignore TAB key here */ + /* do the nickname completion work like on IRC */ + this.completeNick(); + return false; /* do not leave the tab key default behavior */ + } + else if (code == Event.KEY_RETURN) /* enter key */ + { + var w = this.el_words; + var wval = w.value; + + // append the string to the history + this.cmdhistory.push(wval); + this.cmdhistoryid = this.cmdhistory.length; + this.cmdhistoryissearching = false; + + // send the string to the server + re = new RegExp("^(\/[a-z0-9]+)( (.*)|)"); + if (wval.match(re)) + { + /* a user command */ + cmd = wval.replace(re, '$1'); + param = wval.replace(re, '$3'); + this.sendRequest(cmd, param.substr(0, pfc_max_text_len + this.clientid.length)); + } + else + { + /* a classic 'send' command*/ + + // empty messages with only spaces + rx = new RegExp('^[ ]*$','g'); + wval = wval.replace(rx,''); + + /* truncate the text length */ + wval = wval.substr(0,pfc_max_text_len); + + /* colorize the text with current_text_color */ + if (this.current_text_color != '' && wval.length != '') + wval = '[color=#' + this.current_text_color + '] ' + wval + ' [/color]'; + + this.sendRequest('/send', wval); + } + w.value = ''; + return false; + } + else if (code == 33 && false) // page up key + { + // write the last command in the history + if (this.cmdhistory.length>0) + { + var w = this.el_words; + if (this.cmdhistoryissearching == false && w.value != "") + this.cmdhistory.push(w.value); + this.cmdhistoryissearching = true; + this.cmdhistoryid = this.cmdhistoryid-1; + if (this.cmdhistoryid<0) this.cmdhistoryid = this.cmdhistory.length-1; + w.value = this.cmdhistory[this.cmdhistoryid]; + } + } + else if (code == 34 && false) // page down key + { + // write the next command in the history + if (this.cmdhistory.length>0) + { + var w = this.el_words; + if (this.cmdhistoryissearching == false && w.value != "") + this.cmdhistory.push(w.value); + this.cmdhistoryissearching = true; + this.cmdhistoryid = this.cmdhistoryid+1; + if (this.cmdhistoryid>=this.cmdhistory.length) this.cmdhistoryid = 0; + w.value = this.cmdhistory[this.cmdhistoryid]; + } + } + else + { + /* allow other keys */ + return true; + } + }, + /** + * Handle the pressed keys + * see also callbackWords_OnKeypress + */ + callbackWords_OnKeydown: function(evt) + { + if (!this.isconnected) return false; + this.clearError(Array(this.el_words)); + var code = (evt.which) ? evt.which : event.keyCode + if (code == 9) /* tab key */ + { + /* IE workaround : ignore TAB key here */ + /* do the nickname completion work like on IRC */ + this.completeNick(); + return false; /* do not leave the tab key default behavior */ + } + else + { + return true; + } + }, + callbackWords_OnFocus: function(evt) + { + // if (this.el_handle && this.el_handle.value == '' && !this.minmax_status) + // this.el_handle.focus(); + }, + callbackHandle_OnKeydown: function(evt) + { + }, + callbackHandle_OnChange: function(evt) + { + }, + callback_OnUnload: function(evt) + { + /* don't disconnect users when they reload the window + * this event doesn't only occurs when the page is closed but also when the page is reloaded */ + if (pfc_quit_on_closedwindow) + { + if (!this.isconnected) return false; + this.sendRequest('/quit'); + } + }, + + callbackContainer_OnMousemove: function(evt) + { + this.isdraging = true; + }, + callbackContainer_OnMousedown: function(evt) + { + if ( ((is_ie || is_khtml) && evt.button == 1) || (is_ff && evt.button == 0) ) + this.isdraging = false; + }, + callbackContainer_OnMouseup: function(evt) + { + if ( ((is_ie || is_khtml) && evt.button == 1) || (is_ff && evt.button == 0) ) + if (!this.isdraging) + if (this.el_words && !this.minmax_status) + this.el_words.focus(); + }, + + /** + * hide error area and stop blinking fields + */ + clearError: function(ids) + { + this.el_errors.style.display = 'none'; + for (var i=0; i<ids.length; i++) + this.blink(ids[i].id, 'stop'); + }, + + /** + * show error area and assign to it an error message and start the blinking of given fields + */ + setError: function(str, ids) + { + this.el_errors.innerHTML = str; + this.el_errors.style.display = 'block'; + for (var i=0; i<ids.length; i++) + this.blink(ids[i].id, 'start'); + }, + + /** + * blink routines used by Error functions + */ + blink: function(id, action) + { + clearTimeout(this.blinktimeout[id]); + if ($(id) == null) return; + if (action == 'start') + { + this.blinktmp[id] = $(id).style.backgroundColor; + clearTimeout(this.blinktimeout[id]); + this.blinktimeout[id] = setTimeout('pfc.blink(\'' + id + '\',\'loop\')', 500); + } + if (action == 'stop') + { + $(id).style.backgroundColor = this.blinktmp[id]; + } + if (action == 'loop') + { + if (this.blinkloop[id] == 1) + { + $(id).style.backgroundColor = '#FFDFC0'; + this.blinkloop[id] = 2; + } + else + { + $(id).style.backgroundColor = '#FFFFFF'; + this.blinkloop[id] = 1; + } + this.blinktimeout[id] = setTimeout('pfc.blink(\'' + id + '\',\'loop\')', 500); + } + }, + + displayMsg: function( cmd, msg ) + { + // get the current selected tab container + var tabid = this.gui.getTabId(); + var container = this.gui.getChatContentFromTabId(tabid); + + div = document.createElement('div'); + div.style.padding = "2px 5px 2px 5px"; + + pre = document.createElement('pre'); + pre.setAttribute('class', 'pfc_info pfc_info_'+cmd); + pre.setAttribute('className', 'pfc_info pfc_info_'+cmd); // for IE6 + // Element.addClassName(pre, 'pfc_info'); + // Element.addClassName(pre, 'pfc_info_'+cmd); + pre.style.border = "1px solid #555"; + pre.style.padding = "5px"; + pre.innerHTML = msg; + div.appendChild(pre); + + // finaly append this to the message list + container.appendChild(div); + this.gui.scrollDown(tabid, div); + }, + + handleComingRequest: function( cmds ) + { + var msg_html = $H(); + + //alert(cmds.inspect()); + + // var html = ''; + for(var mid = 0; mid < cmds.length ; mid++) + { + var id = cmds[mid][0]; + var date = cmds[mid][1]; + var time = cmds[mid][2]; + var sender = cmds[mid][3]; + var recipientid = cmds[mid][4]; + var cmd = cmds[mid][5]; + var param = cmds[mid][6]; + var fromtoday = cmds[mid][7]; + var oldmsg = cmds[mid][8]; + + // format and post message + var line = ''; + line += '<div id="pfc_msg'+ id +'" class="pfc_cmd_'+ cmd +' pfc_message'; + if (oldmsg == 1) line += ' pfc_oldmsg'; + line += '">'; + line += '<span class="pfc_date'; + if (fromtoday == 1) line += ' pfc_invisible'; + line += '">'+ date +'</span> '; + line += '<span class="pfc_heure">'+ time +'</span> '; + if (cmd == 'send') + { + line += ' <span class="pfc_nick">'; + line += '‹'; + line += '<span '; + line += 'onclick="pfc.insert_text(\'' + sender + ', \',\'\')" '; + line += 'class="pfc_nickmarker pfc_nick_'+ hex_md5(_to_utf8(sender)) +'">'; + line += sender; + line += '</span>'; + line += '›'; + line += '</span> '; + } + if (cmd == 'notice' || cmd == 'me') + line += '<span class="pfc_words">* '+ this.parseMessage(param) +'</span> '; + else + line += '<span class="pfc_words">'+ this.parseMessage(param) +'</span> '; + line += '</div>'; + + // notify the hidden tab a message has been received + if (cmd == 'send' || cmd == 'me') + { + var tabid = recipientid; + if (this.gui.getTabId() != tabid) + this.gui.notifyTab(tabid); + } + + if (msg_html[recipientid] == null) + msg_html[recipientid] = line; + else + msg_html[recipientid] += line; + } + + // loop on all recipients and post messages + var keys = msg_html.keys(); + for( var i=0; i<keys.length; i++) + { + var recipientid = keys[i]; + var tabid = recipientid; + + // create the tab if it doesn't exists yet + var recipientdiv = this.gui.getChatContentFromTabId(tabid); + + // create a dummy div to avoid konqueror bug when setting nickmarkers + var m = document.createElement('div'); + m.innerHTML = msg_html[recipientid]; + this.colorizeNicks(m); + this.refresh_clock(m); + // finaly append this to the message list + recipientdiv.appendChild(m); + this.gui.scrollDown(tabid, m); + } + }, + + /** + * Call the ajax request function + * Will query the server + */ + sendRequest: function(cmd, param) + { + var recipientid = this.gui.getTabId(); + var req = cmd+" "+this.clientid+" "+(recipientid==''?'0':recipientid)+(param?" "+param : ""); + if (pfc_debug) + if (cmd != "/update") alert(req); + return eval('pfc_handleRequest(req);'); + }, + + /** + * update function to poll the server each 'refresh_delay' time + */ + updateChat: function(start) + { + clearTimeout(this.timeout); + if (start) + { + var res = this.sendRequest('/update'); + // adjust the refresh_delay if the connection was lost + if (res == false) { this.refresh_delay = this.refresh_delay * 2; } + // setup the next update + this.timeout = setTimeout('pfc.updateChat(true)', this.refresh_delay); + } + }, + + /** + * insert a smiley + */ + insertSmiley: function(s) + { + this.el_words.value += s; + this.el_words.focus(); + }, + + /** + * fill the nickname list with connected nicknames + */ + updateNickList: function(tabid,lst) + { + // alert('updateNickList: tabid='+tabid+"-lst="+lst.inspect()); + //var tabid = hex_md5(_to_utf8("ch_"+recipient)); + + this.nicklist[tabid] = lst; + var nicks = lst; + var nickdiv = this.gui.getOnlineContentFromTabId(tabid).firstChild; + var ul = document.createElement('ul'); + for (var i=0; i<nicks.length; i++) + { + var li = document.createElement('li'); + if (nicks[i] != this.nickname) + { + // this is someone -> create a privmsg link + var img = document.createElement('img'); + img.setAttribute('src', this.res.getFileUrl('images/user.gif')); + img.alt = this.res.getLabel('Private message'); + img.title = img.alt; + img.style.marginRight = '5px'; + var a = document.createElement('a'); + a.setAttribute('href', ''); + a.pfc_nick = nicks[i]; + a.onclick = function(){pfc.sendRequest('/privmsg', this.pfc_nick); return false;} + a.appendChild(img); + li.appendChild(a); + } + else + { + // this is myself -> do not create a privmsg link + var img = document.createElement('img'); + img.setAttribute('src', this.res.getFileUrl('images/user-me.gif')); + img.alt = ''; + img.title = img.alt; + img.style.marginRight = '5px'; + li.appendChild(img); + } + + + // nobr is not xhtml valid but it's a workeround + // for IE which doesn't support 'white-space: pre' css rule + var nobr = document.createElement('nobr'); + var span = document.createElement('span'); + span.pfc_nick = nicks[i]; + span.onclick = function(){pfc.insert_text(this.pfc_nick+", ",""); return false;} + span.appendChild(document.createTextNode(nicks[i])); + span.setAttribute('class', 'pfc_nickmarker pfc_nick_'+ hex_md5(_to_utf8(nicks[i]))); + span.setAttribute('className', 'pfc_nickmarker pfc_nick_'+ hex_md5(_to_utf8(nicks[i]))); // for IE6 + + // Element.addClassName(span, 'pfc_nickmarker'); + // Element.addClassName(span, 'pfc_nick_'+ hex_md5(_to_utf8(nicks[i]))); + nobr.appendChild(span); + li.appendChild(nobr); + li.style.borderBottom = '1px solid #AAA'; + + ul.appendChild(li); + } + var fc = nickdiv.firstChild; + if (fc) + nickdiv.replaceChild(ul,fc); + else + nickdiv.appendChild(ul,fc); + this.colorizeNicks(nickdiv); + }, + + /** + * clear the nickname list + */ + clearNickList: function() + { + /* + var nickdiv = this.el_online; + var fc = nickdiv.firstChild; + if (fc) nickdiv.removeChild(fc); + */ + }, + + + /** + * clear the message list history + */ + clearMessages: function() + { + //var msgdiv = $('pfc_chat'); + //msgdiv.innerHTML = ''; + }, + + /** + * parse the message + */ + parseMessage: function(msg) + { + var rx = null; + + // parse urls + var rx_url = new RegExp('(^|[^\\"])([a-z]+\:\/\/[a-z0-9.\\/\\?\\=\\&\\-\\_\\#:;]*)([^\\"]|$)','ig'); + var ttt = msg.split(rx_url); + if (ttt.length > 1 && + !navigator.appName.match("Explorer|Konqueror") && + !navigator.appVersion.match("KHTML")) + { + msg = ''; + for( var i = 0; i<ttt.length; i++) + { + var offset = (ttt[i].length - 7) / 2; + var delta = (ttt[i].length - 7 - 60); + var range1 = 7+offset-delta; + var range2 = 7+offset+delta; + if (ttt[i].match(rx_url)) + { + msg = msg + '<a href="' + ttt[i] + '"'; + if (pfc_openlinknewwindow) + msg = msg + ' onclick="window.open(this.href,\'_blank\');return false;"'; + msg = msg + '>' + (delta>0 ? ttt[i].substring(7,range1)+ ' ... ' + ttt[i].substring(range2,ttt[i].length) : ttt[i]) + '</a>'; + } + else + { + msg = msg + ttt[i]; + } + } + } + else + { + // fallback for IE6/Konqueror which do not support split with regexp + replace = '$1<a href="$2"'; + if (pfc_openlinknewwindow) + replace = replace + ' onclick="window.open(this.href,\'_blank\');return false;"'; + replace = replace + '>$2</a>$3'; + msg = msg.replace(rx_url, replace); + } + + // replace double spaces by entity + rx = new RegExp(' ','g'); + msg = msg.replace(rx, ' '); + + // try to parse bbcode + rx = new RegExp('\\[b\\](.+?)\\[\/b\\]','ig'); + msg = msg.replace(rx, '<span style="font-weight: bold">$1</span>'); + rx = new RegExp('\\[i\\](.+?)\\[\/i\\]','ig'); + msg = msg.replace(rx, '<span style="font-style: italic">$1</span>'); + rx = new RegExp('\\[u\\](.+?)\\[\/u\\]','ig'); + msg = msg.replace(rx, '<span style="text-decoration: underline">$1</span>'); + rx = new RegExp('\\[s\\](.+?)\\[\/s\\]','ig'); + msg = msg.replace(rx, '<span style="text-decoration: line-through">$1</span>'); + // rx = new RegExp('\\[pre\\](.+?)\\[\/pre\\]','ig'); + // msg = msg.replace(rx, '<pre>$1</pre>'); + rx = new RegExp('\\[email\\]([A-z0-9][\\w.-]*@[A-z0-9][\\w\\-\\.]+\\.[A-z0-9]{2,6})\\[\/email\\]','ig'); + msg = msg.replace(rx, '<a href="mailto: $1">$1</a>'); + rx = new RegExp('\\[email=([A-z0-9][\\w.-]*@[A-z0-9][\\w\\-\\.]+\\.[A-z0-9]{2,6})\\](.+?)\\[\/email\\]','ig'); + msg = msg.replace(rx, '<a href="mailto: $1">$2</a>'); + rx = new RegExp('\\[color=([a-zA-Z]+|\\#?[0-9a-fA-F]{6}|\\#?[0-9a-fA-F]{3})](.+?)\\[\/color\\]','ig'); + msg = msg.replace(rx, '<span style="color: $1">$2</span>'); + // parse bbcode colors twice because the current_text_color is a bbcolor + // so it's possible to have a bbcode color imbrication + rx = new RegExp('\\[color=([a-zA-Z]+|\\#?[0-9a-fA-F]{6}|\\#?[0-9a-fA-F]{3})](.+?)\\[\/color\\]','ig'); + msg = msg.replace(rx, '<span style="color: $1">$2</span>'); + + // try to parse smileys + var smileys = this.res.getSmileyHash(); + var sl = smileys.keys(); + for(var i = 0; i < sl.length; i++) + { + rx = new RegExp(RegExp.escape(sl[i]),'g'); + msg = msg.replace(rx, '<img src="'+ smileys[sl[i]] +'" alt="' + sl[i] + '" title="' + sl[i] + '" />'); + } + + // try to parse nickname for highlighting + rx = new RegExp('(^|[ :,;])'+RegExp.escape(this.nickname)+'([ :,;]|$)','gi'); + msg = msg.replace(rx, '$1<strong>'+ this.nickname +'</strong>$2'); + + // don't allow to post words bigger than 65 caracteres + // doesn't work with crappy IE and Konqueror ! + rx = new RegExp('([^ \\:\\<\\>\\/\\&\\;]{60})','ig'); + var ttt = msg.split(rx); + if (ttt.length > 1 && + !navigator.appName.match("Explorer|Konqueror") && + !navigator.appVersion.match("KHTML")) + { + msg = ''; + for( var i = 0; i<ttt.length; i++) + { + msg = msg + ttt[i] + ' '; + } + } + return msg; + }, + + /** + * apply nicknames color to the root childs + */ + colorizeNicks: function(root) + { + if (this.nickmarker) + { + var nicklist = this.getElementsByClassName(root, 'pfc_nickmarker', ''); + for(var i = 0; i < nicklist.length; i++) + { + var cur_nick = nicklist[i].innerHTML; + var cur_color = this.getAndAssignNickColor(cur_nick); + nicklist[i].style.color = cur_color; + } + } + }, + + /** + * Initialize the color array used to colirize the nicknames + */ + reloadColorList: function() + { + this.colorlist = pfc_nickname_color_list; + }, + + + /** + * get the corresponding nickname color + */ + getAndAssignNickColor: function(nick) + { + /* check the nickname is colorized or not */ + var allready_colorized = false; + var nc = ''; + for(var j = 0; j < this.nickcolor.length; j++) + { + if (this.nickcolor[j][0] == nick) + { + allready_colorized = true; + nc = this.nickcolor[j][1]; + } + } + if (!allready_colorized) + { + /* reload the color stack if it's empty */ + if (this.colorlist.length == 0) this.reloadColorList(); + /* take the next color from the list and colorize this nickname */ + var cid = Math.round(Math.random()*(this.colorlist.length-1)); + nc = this.colorlist[cid]; + this.colorlist.splice(cid,1); + this.nickcolor.push(new Array(nick, nc)); + } + + return nc; + }, + + + /** + * Colorize with 'color' all the nicknames found as a 'root' child + */ + applyNickColor: function(root, nick, color) + { + + var nicktochange = this.getElementsByClassName(root, 'pfc_nick_'+ hex_md5(_to_utf8(nick)), '') + for(var i = 0; nicktochange.length > i; i++) + nicktochange[i].style.color = color; + + }, + + /** + * Returns a list of elements which have a clsName class + */ + getElementsByClassName: function( root, clsName, clsIgnore ) + { + var i, matches = new Array(); + var els = root.getElementsByTagName('*'); + var rx1 = new RegExp('.*'+clsName+'.*'); + var rx2 = new RegExp('.*'+clsIgnore+'.*'); + for(i=0; i<els.length; i++) { + if(els.item(i).className.match(rx1) && + (clsIgnore == '' || !els.item(i).className.match(rx2)) ) { + matches.push(els.item(i)); + } + } + return matches; + }, + + showClass: function(root, clsName, clsIgnore, show) + { + var elts = this.getElementsByClassName(root, clsName, clsIgnore); + for(var i = 0; elts.length > i; i++) + if (show) + elts[i].style.display = 'inline'; + else + elts[i].style.display = 'none'; + }, + + + /** + * Nickname marker show/hide + */ + nickmarker_swap: function() + { + if (this.nickmarker) { + this.nickmarker = false; + } else { + this.nickmarker = true; + } + this.refresh_nickmarker() + setCookie('pfc_nickmarker', this.nickmarker); + }, + refresh_nickmarker: function(root) + { + var nickmarker_icon = $('pfc_nickmarker'); + if (!root) root = $('pfc_channels_content'); + if (this.nickmarker) + { + nickmarker_icon.src = this.res.getFileUrl('images/color-on.gif'); + nickmarker_icon.alt = this.res.getLabel("Hide nickname marker"); + nickmarker_icon.title = nickmarker_icon.alt; + this.colorizeNicks(root); + } + else + { + nickmarker_icon.src = this.res.getFileUrl('images/color-off.gif'); + nickmarker_icon.alt = this.res.getLabel("Show nickname marker"); + nickmarker_icon.title = nickmarker_icon.alt; + var elts = this.getElementsByClassName(root, 'pfc_nickmarker', ''); + for(var i = 0; elts.length > i; i++) + { + // this is not supported in konqueror =>>> elts[i].removeAttribute('style'); + elts[i].style.color = ''; + } + } + }, + + + /** + * Date/Hour show/hide + */ + clock_swap: function() + { + if (this.clock) { + this.clock = false; + } else { + this.clock = true; + } + this.refresh_clock(); + setCookie('pfc_clock', this.clock); + }, + refresh_clock: function( root ) + { + var clock_icon = $('pfc_clock'); + if (!root) root = $('pfc_channels_content'); + if (this.clock) + { + clock_icon.src = this.res.getFileUrl('images/clock-on.gif'); + clock_icon.alt = this.res.getLabel('Hide dates and hours'); + clock_icon.title = clock_icon.alt; + this.showClass(root, 'pfc_date', 'pfc_invisible', true); + this.showClass(root, 'pfc_heure', 'pfc_invisible', true); + } + else + { + clock_icon.src = this.res.getFileUrl('images/clock-off.gif'); + clock_icon.alt = this.res.getLabel('Show dates and hours'); + clock_icon.title = clock_icon.alt; + this.showClass(root, 'pfc_date', 'pfc_invisible', false); + this.showClass(root, 'pfc_heure', 'pfc_invisible', false); + } + // browser automaticaly scroll up misteriously when showing the dates + // $('pfc_chat').scrollTop += 30; + }, + + /** + * Connect/disconnect button + */ + connect_disconnect: function() + { + if (this.isconnected) + this.sendRequest('/quit'); + else + this.sendRequest('/connect'); + }, + refresh_loginlogout: function() + { + var loginlogout_icon = $('pfc_loginlogout'); + if (this.isconnected) + { + // this.updateNickList(this.nicklist); + loginlogout_icon.src = this.res.getFileUrl('images/logout.gif'); + loginlogout_icon.alt = this.res.getLabel('Disconnect'); + loginlogout_icon.title = loginlogout_icon.alt; + } + else + { + this.clearMessages(); + this.clearNickList(); + loginlogout_icon.src = this.res.getFileUrl('images/login.gif'); + loginlogout_icon.alt = this.res.getLabel('Connect'); + loginlogout_icon.title = loginlogout_icon.alt; + } + }, + + + + /** + * Minimize/Maximized the chat zone + */ + swap_minimize_maximize: function() + { + if (this.minmax_status) { + this.minmax_status = false; + } else { + this.minmax_status = true; + } + setCookie('pfc_minmax_status', this.minmax_status); + this.refresh_minimize_maximize(); + }, + refresh_minimize_maximize: function() + { + var content = $('pfc_content_expandable'); + var btn = $('pfc_minmax'); + if (this.minmax_status) + { + btn.src = this.res.getFileUrl('images/maximize.gif'); + btn.alt = this.res.getLabel('Magnify'); + btn.title = btn.alt; + content.style.display = 'none'; + } + else + { + btn.src = this.res.getFileUrl('images/minimize.gif'); + btn.alt = this.res.getLabel('Cut down'); + btn.title = btn.alt; + content.style.display = 'block'; + } + }, + + /** + * BBcode ToolBar + */ + insert_text: function(open, close) + { + var msgfield = $('pfc_words'); + + // IE support + if (document.selection && document.selection.createRange) + { + msgfield.focus(); + sel = document.selection.createRange(); + sel.text = open + sel.text + close; + msgfield.focus(); + } + + // Moz support + else if (msgfield.selectionStart || msgfield.selectionStart == '0') + { + var startPos = msgfield.selectionStart; + var endPos = msgfield.selectionEnd; + + msgfield.value = msgfield.value.substring(0, startPos) + open + msgfield.value.substring(startPos, endPos) + close + msgfield.value.substring(endPos, msgfield.value.length); + msgfield.selectionStart = msgfield.selectionEnd = endPos + open.length + close.length; + msgfield.focus(); + } + + // Fallback support for other browsers + else + { + msgfield.value += open + close; + msgfield.focus(); + } + return; + }, + + /** + * Minimize/Maximize none/inline + */ + minimize_maximize: function(idname, type) + { + var element = $(idname); + if(element.style) + { + if(element.style.display == type ) + { + element.style.display = 'none'; + } + else + { + element.style.display = type; + } + } + }, + + switch_text_color: function(color) + { + /* clear any existing borders on the color buttons */ + var colorbtn = this.getElementsByClassName($('pfc_colorlist'), 'pfc_color', ''); + for(var i = 0; colorbtn.length > i; i++) + colorbtn[i].style.border = 'none'; + + /* assign the new border style to the selected button */ + this.current_text_color = color; + setCookie('pfc_current_text_color', this.current_text_color); + var idname = 'pfc_color_' + color; + $(idname).style.border = '1px solid #666'; + $(idname).style.padding = '1px'; + + // assigne the new color to the input text box + this.el_words.style.color = '#'+color; + this.el_words.focus(); + }, + + /** + * Smiley show/hide + */ + showHideSmileys: function() + { + if (this.showsmileys) + { + this.showsmileys = false; + } + else + { + this.showsmileys = true; + } + setCookie('pfc_showsmileys', this.showsmileys); + this.refresh_Smileys(); + }, + refresh_Smileys: function() + { + // first of all : show/hide the smiley box + var content = $('pfc_smileys'); + if (this.showsmileys) + content.style.display = 'block'; + else + content.style.display = 'none'; + + // then switch the button icon + var btn = $('pfc_showHideSmileysbtn'); + if (this.showsmileys) + { + if (btn) + { + btn.src = this.res.getFileUrl('images/smiley-on.gif'); + btn.alt = this.res.getLabel('Hide smiley box'); + btn.title = btn.alt; + } + } + else + { + if (btn) + { + btn.src = this.res.getFileUrl('images/smiley-off.gif'); + btn.alt = this.res.getLabel('Show smiley box'); + btn.title = btn.alt; + } + } + }, + + + /** + * Show Hide who's online + */ + showHideWhosOnline: function() + { + if (this.showwhosonline) + { + this.showwhosonline = false; + } + else + { + this.showwhosonline = true; + } + setCookie('pfc_showwhosonline', this.showwhosonline); + this.refresh_WhosOnline(); + }, + refresh_WhosOnline: function() + { + // first of all : show/hide the nickname list box + var root = $('pfc_channels_content'); + var contentlist = this.getElementsByClassName(root, 'pfc_online', ''); + for(var i = 0; i < contentlist.length; i++) + { + var content = contentlist[i]; + if (this.showwhosonline) + content.style.display = 'block'; + else + content.style.display = 'none'; + content.style.zIndex = '100'; // for IE6, force the nickname list borders to be shown + } + + // then refresh the button icon + var btn = $('pfc_showHideWhosOnlineBtn'); + if (!btn) return; + if (this.showwhosonline) + { + btn.src = this.res.getFileUrl('images/online-on.gif'); + btn.alt = this.res.getLabel('Hide online users box'); + btn.title = btn.alt; + } + else + { + btn.src = this.res.getFileUrl('images/online-off.gif'); + btn.alt = this.res.getLabel('Show online users box'); + btn.title = btn.alt; + } + this.refresh_Chat(); + }, + + /** + * Resize chat + */ + refresh_Chat: function() + { + // resize all the tabs content + var root = $('pfc_channels_content'); + var contentlist = this.getElementsByClassName(root, 'pfc_chat', ''); + for(var i = 0; i < contentlist.length; i++) + { + var chatdiv = contentlist[i]; + var style = $H(); + if (!this.showwhosonline) + { + chatdiv.style.width = '100%'; + } + else + { + chatdiv.style.width = ''; + } + } + } +}; Added: trunk/src/client/pfcgui.js =================================================================== --- trunk/src/client/pfcgui.js (rev 0) +++ trunk/src/client/pfcgui.js 2006-08-17 21:10:14 UTC (rev 677) @@ -0,0 +1,568 @@ +/** + * This class centralize the pfc' Graphic User Interface manipulations + * (depends on prototype library) + * @author Stephane Gully + */ +var pfcGui = Class.create(); +pfcGui.prototype = { + + initialize: function() + { + this.current_tab = ''; + this.current_tab_id = ''; + this.tabs = Array(); + this.tabids = Array(); + this.tabtypes = Array(); + this.chatcontent = $H(); + this.onlinecontent = $H(); + this.scrollpos = $H(); + this.elttoscroll = $H(); + }, + + /** + * scroll down from the posted message height + */ + scrollDown: function(tabid, elttoscroll) + { + if (this.getTabId() != tabid) + { + if (!this.elttoscroll[tabid]) this.elttoscroll[tabid] = Array(); + this.elttoscroll[tabid].push(elttoscroll); + return; + } + var content = this.getChatContentFromTabId(tabid); + content.scrollTop += elttoscroll.offsetHeight+2; + this.scrollpos[tabid] = content.scrollTop; + }, + + isCreated: function(tabid) + { + /* + for (var i = 0; i < this.tabids.length ; i++) + { + if (this.tabids[i] == tabid) return true; + } + return false; + */ + return (indexOf(this.tabids, tabid) >= 0); + }, + + setTabById: function(tabid) + { + // first of all save the scroll pos of the visible tab + var content = this.getChatContentFromTabId(this.current_tab_id); + this.scrollpos[this.current_tab_id] = content.scrollTop; + + // start without selected tabs + this.current_tab = ''; + this.current_tab_id = ''; + var tab_to_show = null; + // try to fine the tab to select and select it! + for (var i=0; i<this.tabids.length; i++) + { + var tabtitle = $('pfc_channel_title'+this.tabids[i]); + var tabcontent = $('pfc_channel_content'+this.tabids[i]); + if (this.tabids[i] == tabid) + { + // select the tab + tabtitle.setAttribute('class', 'selected'); + tabtitle.setAttribute('className', 'selected'); // for IE6 + //Element.addClassName(tabtitle, 'selected'); + tab_to_show = tabcontent; + this.current_tab = this.tabs[i]; + this.current_tab_id = tabid; + } + else + { + // unselect the tab + tabtitle.setAttribute('class', ''); + tabtitle.setAttribute('className', ''); // for IE6 + //Element.removeClassName(tabtitle, 'selected'); + tabcontent.style.display = 'none'; + } + } + + // show the new selected tab + tab_to_show.style.display = 'block'; + + // restore the scroll pos + var content = this.getChatContentFromTabId(tabid); + content.scrollTop = this.scrollpos[tabid]; + + // scroll the new posted message + if (this.elttoscroll[tabid] && + this.elttoscroll[tabid].length > 0) + { + // on by one + for (var i=0; i<this.elttoscroll[tabid].length; i++) + this.scrollDown(tabid,this.elttoscroll[tabid][i]); + this.elttoscroll[tabid] = Array(); + } + + this.unnotifyTab(tabid); + }, + + getTabId: function() + { + return this.current_tab_id; + }, + + getChatContentFromTabId: function(tabid) + { + // return the chat content if it exists + var cc = this.chatcontent[tabid]; + if (cc) return cc; + + // if the chat content doesn't exists yet, just create a cached one + cc = document.createElement('div'); + cc.setAttribute('id', 'pfc_chat_'+tabid); + cc.setAttribute('class', 'pfc_chat'); + cc.setAttribute('className', 'pfc_chat'); // for IE6 + + // Element.addClassName(cc, 'pfc_chat'); + cc.style.display = "block"; // needed by IE6 to show the online div at startup (first loaded page) + // cc.style.marginLeft = "5px"; + + this.chatcontent[tabid] = cc; + return cc; + }, + getOnlineContentFromTabId: function(tabid) + { + // return the online content if it exists + var oc = this.onlinecontent[tabid]; + if (oc) return oc; + + oc = document.createElement('div'); + oc.setAttribute('id', 'pfc_online_'+tabid); + oc.setAttribute('class', 'pfc_online'); + oc.setAttribute('className', 'pfc_online'); // for IE6 + //Element.addClassName(oc, 'pfc_online'); + // I set the border style here because seting it in the CSS is not taken in account + // oc.style.borderLeft = "1px solid #555"; + oc.style.display = "block"; // needed by IE6 to show the online div at startup (first loaded page) + + // Create a dummy div to add padding + var div = document.createElement('div'); + div.style.padding = "5px"; + oc.appendChild(div); + + this.onlinecontent[tabid] = oc; + return oc; + }, + + removeTabById: function(tabid) + { + // remove the widgets + var tabparent_t = $('pfc_channels_list'); + var tabparent_c = $('pfc_channels_content'); + var tab_t = $('pfc_channel_title'+tabid); + var tab_c = $('pfc_channel_content'+tabid); + tabparent_t.removeChild(tab_t); + tabparent_c.removeChild(tab_c); + + // empty the chat div content + var div_chat = this.getChatContentFromTabId(tabid); + div_chat.innerHTML = ''; + + // remove the tab from the list + var tabpos = indexOf(this.tabids, tabid); + var name = this.tabs[tabpos]; + this.tabids = without(this.tabids, this.tabids[tabpos]); + this.tabs = without(this.tabs, this.tabs[tabpos]); + this.tabtypes = without(this.tabtypes, this.tabtypes[tabpos]); + tabpos = indexOf(this.tabids, this.getTabId()); + if (tabpos<0) tabpos = 0; + this.setTabById(this.tabids[tabpos]); + return name; + }, + + /* + removeTabByName: function(name) + { + var tabid = hex_md5(_to_utf8(name)); + var ret = this.removeTabById(tabid); + if (ret == name) + return tabid; + else + return 0; + }, + */ + + createTab: function(name, tabid, type) + { + // do not create empty tabs + if(name == '') return; + if(tabid == '') return; + + // do not create twice a the same tab + if (this.isCreated(tabid)) return; + + // var tabid = hex_md5(_to_utf8(name)); + //alert(name+'='+tabid); + this.tabs.push(name); + this.tabids.push(tabid); + this.tabtypes.push(type); + + //alert(this.tabs.toString()); + + var li_title = document.createElement('li'); + li_title.setAttribute('id', 'pfc_channel_title'+tabid); + + var li_div = document.createElement('div'); + li_title.appendChild(li_div); + + var img = document.createElement('img'); + img.setAttribute('id', 'pfc_tabimg'+tabid); + if (type == 'ch') + img.setAttribute('src', pfc.res.getFileUrl('images/ch.gif')); + if (type == 'pv') + img.setAttribute('src', pfc.res.getFileUrl('images/pv.gif')); + var a1 = document.createElement('a'); + // Element.addClassName(a1, 'pfc_tabtitle'); + a1.setAttribute('class', 'pfc_tabtitle'); + a1.setAttribute('className', 'pfc_tabtitle'); // for IE6 + a1.appendChild(img); + a1.appendChild(document.createTextNode(name)); + a1.setAttribute('href', '#'); + a1.pfc_tabid = tabid; + a1.onclick = function(){pfc.gui.setTabById(this.pfc_tabid); return false;} + li_div.appendChild(a1); + + var a2 = document.createElement('a'); + a2.pfc_tabid = tabid; + a2.onclick = function(){ + var res = confirm(pfc.res.getLabel('Do you really want to leave this room ?')); + if (res == true) pfc.sendRequest('/leave', this.pfc_tabid); return false; + } + a2.alt = pfc.res.getLabel('Close this tab'); + a2.title = a2.alt; + // Element.addClassName(a2, 'pfc_tabclose'); + a2.setAttribute('class', 'pfc_tabclose'); + a2.setAttribute('className', 'pfc_tabclose'); // for IE6 + var img = document.createElement('img'); + img.setAttribute('src', pfc.res.getFileUrl('images/tab_remove.gif')); + a2.appendChild(img); + li_div.appendChild(a2); + + var div_content = document.createElement('div'); + div_content.setAttribute('id', 'pfc_channel_content'+tabid); + // Element.addClassName(div_content, 'pfc_content'); + div_content.setAttribute('class', 'pfc_content'); + div_content.setAttribute('className', 'pfc_content'); // for IE6 + div_content.style.display = 'none'; + + var div_chat = this.getChatContentFromTabId(tabid); + var div_online = this.getOnlineContentFromTabId(tabid); + div_content.appendChild(div_chat); + div_content.appendChild(div_online); + + $('pfc_channels_list').appendChild(li_title); + $('pfc_channels_content').appendChild(div_content); + + return tabid; + }, + + /** + * This function change the tab icon in order to catch the attention + */ + notifyTab: function(tabid) + { + var tabpos = indexOf(this.tabids, tabid); + var tabtype = this.tabtypes[tabpos]; + var img = $('pfc_tabimg'+tabid); + if (img) ... [truncated message content] |