1/** 2 * This class centralize the pfc' Graphic User Interface manipulations 3 * (depends on prototype library) 4 * @author Stephane Gully 5 */ 6var pfcGui = Class.create(); 7pfcGui.prototype = { 8 9 initialize: function() 10 { 11// this.builder = new pfcGuiBuilder(); 12 this.current_tab = ''; 13 this.current_tab_id = ''; 14 this.tabs = Array(); 15 this.tabids = Array(); 16 this.tabtypes = Array(); 17 this.chatcontent = $H(); 18 this.onlinecontent = $H(); 19 this.scrollpos = $H(); 20 this.elttoscroll = $H(); 21 this.windownotifynb = 0; 22 }, 23 24 /** 25 * Scroll down the message list area by elttoscroll height 26 * - elttoscroll is a message DOM element which has been appended to the tabid's message list 27 * - this.elttoscroll is an array containing the list of messages that will be scrolled 28 * when the corresponding tab will be shown (see setTabById bellow). 29 * It is necessary to keep in cache the list of hidden (because the tab is inactive) messages 30 * because the 'scrollTop' javascript attribute 31 * will not work if the element (tab content) is hidden. 32 */ 33 scrollDown: function(tabid, elttoscroll) 34 { 35 // check the wanted tabid is the current active one 36 if (this.getTabId() != tabid) 37 { 38 // no it's not the current active one so just cache the elttoscroll in the famouse this.elttoscroll array 39 if (!this.elttoscroll.get(tabid)) this.elttoscroll.set(tabid, Array()); 40 this.elttoscroll.get(tabid).push(elttoscroll); 41 return; 42 } 43 // the wanted tab is active so just scroll down the tab content element 44 // by elttoscroll element height (use 'offsetHeight' attribute) 45 var content = this.getChatContentFromTabId(tabid); 46 47 // the next line seems to help with IE6 scroll on the first load 48 // http://sourceforge.net/tracker/index.php?func=detail&aid=1568264&group_id=158880&atid=809601 49 var dudVar = content.scrollTop; 50 content.scrollTop += elttoscroll.offsetHeight+2; 51 this.scrollpos.set(tabid, content.scrollTop); 52 }, 53 54 isCreated: function(tabid) 55 { 56 /* 57 for (var i = 0; i < this.tabids.length ; i++) 58 { 59 if (this.tabids[i] == tabid) return true; 60 } 61 return false; 62 */ 63 return (indexOf(this.tabids, tabid) >= 0); 64 }, 65 66 setTabById: function(tabid) 67 { 68 var className = (!is_ie7 && !is_ie6) ? 'class' : 'className'; 69 70 // first of all save the scroll pos of the visible tab 71 var content = this.getChatContentFromTabId(this.current_tab_id); 72 this.scrollpos.set(this.current_tab_id, content.scrollTop); 73 74 // start without selected tabs 75 this.current_tab = ''; 76 this.current_tab_id = ''; 77 var tab_to_show = null; 78 // try to fine the tab to select and select it! 79 for (var i=0; i<this.tabids.length; i++) 80 { 81 var tabtitle = $('pfc_channel_title'+this.tabids[i]); 82 var tabcontent = $('pfc_channel_content'+this.tabids[i]); 83 if (this.tabids[i] == tabid) 84 { 85 // select the tab 86 tabtitle.setAttribute(className, 'selected'); 87 //Element.addClassName(tabtitle, 'selected'); 88 tab_to_show = tabcontent; 89 this.current_tab = this.tabs[i]; 90 this.current_tab_id = tabid; 91 } 92 else 93 { 94 // unselect the tab 95 tabtitle.setAttribute(className, ''); 96 //Element.removeClassName(tabtitle, 'selected'); 97 tabcontent.style.display = 'none'; 98 } 99 } 100 101 // show the new selected tab 102 tab_to_show.style.display = 'block'; 103 104 // restore the scroll pos 105 var content = this.getChatContentFromTabId(tabid); 106 content.scrollTop = this.scrollpos.get(tabid); 107 108 // scroll the new posted message 109 if (this.elttoscroll.get(tabid) && 110 this.elttoscroll.get(tabid).length > 0) 111 { 112 // on by one 113 for (var i=0; i<this.elttoscroll.get(tabid).length; i++) 114 this.scrollDown(tabid,this.elttoscroll.get(tabid)[i]); 115 // empty the cached element list because it has been scrolled 116 this.elttoscroll.set(tabid, Array()); 117 } 118 119 this.unnotifyTab(tabid); 120 }, 121 122 getTabId: function() 123 { 124 return this.current_tab_id; 125 }, 126 127 getChatContentFromTabId: function(tabid) 128 { 129 var className = (!is_ie7 && !is_ie6) ? 'class' : 'className'; 130 131 // return the chat content if it exists 132 var cc = this.chatcontent.get(tabid); 133 if (cc) return cc; 134 135 // if the chat content doesn't exists yet, just create a cached one 136 cc = document.createElement('div'); 137 cc.setAttribute('id', 'pfc_chat_'+tabid); 138 cc.setAttribute(className, 'pfc_chat'); 139 140 // Element.addClassName(cc, 'pfc_chat'); 141 cc.style.display = "block"; // needed by IE6 to show the online div at startup (first loaded page) 142 // cc.style.marginLeft = "5px"; 143 144 this.chatcontent.set(tabid,cc); 145 return cc; 146 }, 147 getOnlineContentFromTabId: function(tabid) 148 { 149 var className = (!is_ie7 && !is_ie6) ? 'class' : 'className'; 150 151 // return the online content if it exists 152 var oc = this.onlinecontent.get(tabid); 153 if (oc) return oc; 154 155 oc = document.createElement('div'); 156 oc.setAttribute('id', 'pfc_online_'+tabid); 157 oc.setAttribute(className, 'pfc_online'); 158 //Element.addClassName(oc, 'pfc_online'); 159 // I set the border style here because seting it in the CSS is not taken in account 160 // oc.style.borderLeft = "1px solid #555"; 161 oc.style.display = "block"; // needed by IE6 to show the online div at startup (first loaded page) 162 163 this.onlinecontent.set(tabid,oc); 164 return oc; 165 }, 166 167 removeTabById: function(tabid) 168 { 169 // remove the widgets 170 var tabparent_t = $('pfc_channels_list'); 171 var tabparent_c = $('pfc_channels_content'); 172 var tab_t = $('pfc_channel_title'+tabid); 173 var tab_c = $('pfc_channel_content'+tabid); 174 tabparent_t.removeChild(tab_t); 175 tabparent_c.removeChild(tab_c); 176 177 // empty the chat div content 178 var div_chat = this.getChatContentFromTabId(tabid); 179 div_chat.innerHTML = ''; // do not use ".update('')" or ".remove()" because it do not works on IE6 180 181 // remove the tab from the list 182 var tabpos = indexOf(this.tabids, tabid); 183 var name = this.tabs[tabpos]; 184 this.tabids = without(this.tabids, this.tabids[tabpos]); 185 this.tabs = without(this.tabs, this.tabs[tabpos]); 186 this.tabtypes = without(this.tabtypes, this.tabtypes[tabpos]); 187 tabpos = indexOf(this.tabids, this.getTabId()); 188 if (tabpos<0) tabpos = 0; 189 if (this.tabids[tabpos]) 190 this.setTabById(this.tabids[tabpos]); 191 return name; 192 }, 193 194 /* 195 removeTabByName: function(name) 196 { 197 var tabid = _to_utf8(name).md5(); 198 var ret = this.removeTabById(tabid); 199 if (ret == name) 200 return tabid; 201 else 202 return 0; 203 }, 204 */ 205 206 createTab: function(name, tabid, type) 207 { 208 var className = (!is_ie7 && !is_ie6) ? 'class' : 'className'; 209 210 // do not create empty tabs 211 if(name == '') return; 212 if(tabid == '') return; 213 214 // do not create twice a the same tab 215 if (this.isCreated(tabid)) return; 216 217 // var tabid = _to_utf8(name).md5(); 218 //alert(name+'='+tabid); 219 this.tabs.push(name); 220 this.tabids.push(tabid); 221 this.tabtypes.push(type); 222 223 //alert(this.tabs.toString()); 224 225 var li_title = document.createElement('li'); 226 li_title.setAttribute('id', 'pfc_channel_title'+tabid); 227 228 var li_div = document.createElement('div'); 229 li_div.setAttribute('id', 'pfc_tabdiv'+tabid); 230 li_title.appendChild(li_div); 231 232 var a1 = document.createElement('a'); 233 a1.setAttribute(className, 'pfc_tabtitle'); 234 a1.setAttribute('href', '#'); 235 a1.pfc_tabid = tabid; 236 a1.onclick = function(){pfc.gui.setTabById(this.pfc_tabid); return false;} 237 li_div.appendChild(a1); 238 239 if (pfc_displaytabimage) 240 { 241 var img = document.createElement('img'); 242 img.setAttribute('id', 'pfc_tabimg'+tabid); 243 if (type == 'ch') 244 img.setAttribute('src', pfc.res.getFileUrl('images/ch.gif')); 245 if (type == 'pv') 246 img.setAttribute('src', pfc.res.getFileUrl('images/pv.gif')); 247 a1.appendChild(img); 248 } 249 250 // on ajoute le nom du channel 251 a1.appendChild(document.createTextNode(name)); 252 253 if (pfc_displaytabclosebutton || type == 'pv') 254 { 255 var a2 = document.createElement('a'); 256 a2.pfc_tabid = tabid; 257 a2.pfc_tabname = name; 258 a2.pfc_tabtype = type; 259 a2.onclick = function(){ 260 var msg = (type == 'pv' ? 'Are you sure you want to close this tab ?' : 261 'Do you really want to leave this room ?'); 262 var res = confirm(pfc.res.getLabel(msg)); 263 if (res == true) 264 pfc.sendRequest('/leave',this.pfc_tabid); 265 return false; 266 } 267 a2.alt = pfc.res.getLabel('Close this tab'); 268 a2.title = a2.alt; 269 a2.setAttribute(className, 'pfc_tabclose'); 270 var img = document.createElement('img'); 271 img.setAttribute('src', pfc.res.getFileUrl('images/tab_remove.gif')); 272 a2.appendChild(img); 273 li_div.appendChild(a2); 274 } 275 276 var div_content = document.createElement('div'); 277 div_content.setAttribute('id', 'pfc_channel_content'+tabid); 278 // Element.addClassName(div_content, 'pfc_content'); 279 div_content.setAttribute(className, 'pfc_content'); 280 div_content.style.display = 'none'; 281 282 var div_chat = this.getChatContentFromTabId(tabid); 283 var div_online = this.getOnlineContentFromTabId(tabid); 284 div_content.appendChild(div_chat); 285 div_content.appendChild(div_online); 286 287 $('pfc_channels_list').appendChild(li_title); 288 $('pfc_channels_content').appendChild(div_content); 289 290 // force the height of the chat/online zone in pixel in order fix blank screens on IE6 291 div_chat.style.height = ($('pfc_channels_content').offsetHeight-1)+'px'; 292 div_online.style.height = ($('pfc_channels_content').offsetHeight-1)+'px'; 293 294 return tabid; 295 }, 296 297 /** 298 * This function change the window title in order to catch the attention 299 */ 300 notifyWindow: function() 301 { 302 this.windownotifynb += 1; 303 var rx = new RegExp('^\\[[0-9]+\\](.*)','ig'); 304 document.title = document.title.replace(rx,'$1'); 305 document.title = '['+this.windownotifynb+']'+document.title; 306 307 // play the sound 308 var soundcontainer = document.getElementById('pfc_sound_container'); 309 if (pfc.issoundenable) 310 { 311 var flash = '<object style="visibility:hidden" classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" width="0" height="0">'; 312 flash += '<param name="movie" value="' + pfc.res.getFileUrl('sound.swf') + '">'; 313 flash += '<param name="quality" value="High">'; 314 flash += '<embed style="visibility:hidden" src="' + pfc.res.getFileUrl('sound.swf') + '" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="0" height="0" />'; 315 flash += '</object>'; 316 soundcontainer.innerHTML = flash; 317 } 318 }, 319 unnotifyWindow: function() 320 { 321 this.windownotifynb = 0; 322 var rx = new RegExp('^\\[[0-9]+\\](.*)','ig'); 323 document.title = document.title.replace(rx,'$1'); 324 325 // stop the sound 326 var soundcontainer = document.getElementById('pfc_sound_container'); 327 if (pfc.issoundenable) 328 soundcontainer.innerHTML = ''; 329 }, 330 331 /** 332 * This function change the tab icon in order to catch the attention 333 */ 334 notifyTab: function(tabid) 335 { 336 var className = (!is_ie7 && !is_ie6) ? 'class' : 'className'; 337 338 // first of all be sure the tab highlighting is cleared 339 this.unnotifyTab(tabid); 340 341 var tabpos = indexOf(this.tabids, tabid); 342 var tabtype = this.tabtypes[tabpos]; 343 344 // handle the tab's image modification 345 var img = $('pfc_tabimg'+tabid); 346 if (img) 347 { 348 if (tabtype == 'ch') 349 img.src = pfc.res.getFileUrl('images/ch-active.gif'); 350 if (tabtype == 'pv') 351 img.src = pfc.res.getFileUrl('images/pv-active.gif'); 352 } 353 354 // handle the blicking effect 355 var div = $('pfc_tabdiv'+tabid); 356 if (div) 357 { 358 if (div.blinkstat == true) 359 { 360 div.setAttribute(className, 'pfc_tabblink1'); 361 } 362 else 363 { 364 div.setAttribute(className, 'pfc_tabblink2'); 365 } 366 div.blinkstat = !div.blinkstat; 367 div.blinktimeout = setTimeout('pfc.gui.notifyTab(\''+tabid+'\');', 500); 368 } 369 }, 370 371 /** 372 * This function restore the tab icon to its default value 373 */ 374 unnotifyTab: function(tabid) 375 { 376 var className = (!is_ie7 && !is_ie6) ? 'class' : 'className'; 377 378 var tabpos = indexOf(this.tabids, tabid); 379 var tabtype = this.tabtypes[tabpos]; 380 381 // restore the tab's image 382 var img = $('pfc_tabimg'+tabid); 383 if (img) 384 { 385 if (tabtype == 'ch') 386 img.src = pfc.res.getFileUrl('images/ch.gif'); 387 if (tabtype == 'pv') 388 img.src = pfc.res.getFileUrl('images/pv.gif'); 389 } 390 391 // stop the blinking effect 392 var div = $('pfc_tabdiv'+tabid); 393 if (div) 394 { 395 div.removeAttribute(className); 396 clearTimeout(div.blinktimeout); 397 } 398 }, 399 400 loadSmileyBox: function() 401 { 402 var container = $('pfc_smileys'); 403 var smileys = pfc.res.getSmileyReverseHash();//getSmileyHash(); 404 var sl = smileys.keys(); 405 pfc.res.sortSmileyKeys(); // Sort smiley keys once. 406 for(var i = 0; i < sl.length; i++) 407 { 408 s_url = sl[i]; 409 s_symbol = smileys.get(sl[i]); 410 s_symbol = s_symbol.unescapeHTML(); 411 // Replace " with " for IE and Webkit browsers. 412 // The prototype.js version 1.5.1.1 unescapeHTML() function does not do this. 413 if (is_ie || is_webkit) 414 s_symbol = s_symbol.replace(/"/g,'"'); 415 416 var img = document.createElement('img'); 417 img.setAttribute('src', s_url); 418 img.setAttribute('alt', s_symbol); 419 img.setAttribute('title', s_symbol); 420 img.s_symbol = s_symbol; 421 img.onclick = function(){ pfc.insertSmiley(this.s_symbol); } 422 container.appendChild(img); 423 container.appendChild(document.createTextNode(' ')); // so smileys will wrap fine if lot of smiles in theme. 424 } 425 }, 426 427 loadBBCodeColorList: function() 428 { 429 var className = (!is_ie7 && !is_ie6) ? 'class' : 'className'; 430 431 // color list 432 var clist = $('pfc_colorlist'); 433 var clist_v = pfc_bbcode_color_list; 434 for (var i=0 ; i<clist_v.length ; i++) 435 { 436 var bbc = clist_v[i]; 437 var elt = document.createElement('img'); 438 elt.bbc = bbc; 439 elt.setAttribute(className, 'pfc_color'); 440 elt.setAttribute('id', 'pfc_color_'+bbc); 441 elt.style.backgroundColor = '#'+bbc; 442 elt.setAttribute('src', pfc.res.getFileUrl('images/color_transparent.gif')); 443 elt.setAttribute('alt', bbc); 444 elt.onclick = function(){ pfc.switch_text_color(this.bbc); } 445 clist.appendChild(elt); 446 } 447 } 448}; 449