Ajax.PeriodicalUpdater = Class.create(); Class.inherit( Ajax.PeriodicalUpdater, Ajax.Base, { initialize: function(_options) { this.setOptions(_options); this._options.onComplete = this.requestComplete.bind(this); this._options.onException = this.handleException.bind(this); this._options.onTimeout = this.handleTimeout.bind(this); this._options.timeout = 5000; this.frequency = (this._options.frequency || 2); this.updater = {}; this.update(); }, handleException: function(_request, ex) { if( this._options.handleError ) this._options.handleError("offline, reconnecting"); this.stopUpdate(); this.timer = setTimeout(this.update.bind(this), 1000); }, handleTimeout: function(_request) { if( this._options.handleError ) this._options.handleError("timeout, reconnecting"); this.stopUpdate(); this.timer = setTimeout(this.update.bind(this), 1000); }, stopUpdate: function() { if( this.updater._options ) this.updater._options.onComplete = undefined; clearTimeout(this.timer); }, update: function() { if( this._options.updateParams ) this._options.parameters = (this._options.updateParams)(); this.updater = new Ajax.Request(this._options.url, this._options); }, requestComplete: function(presponse) { try { var xmlRoot = Ajax.getXml(presponse); if( xmlRoot ) { (this._options.updateContent || Ajax.emptyFunction)( xmlRoot ); } else { if( this._options.handleError ) this._options.handleError("reconnecting"); } } catch(e) { } this.timer = setTimeout(this.update.bind(this), this.frequency * 1000); } }); var HtmlGenerationUtils = { popupLink: function(link, title, wndid, inner, width, height,linkclass) { return ''+ inner+''; }, generateOneRowTable: function(content) { return '' + content + '
'; }, viewOpenCell: function(username,servlet,id,canview,canopen,ban,message,cantakenow) { var cellsCount = 2; var link = servlet+"?thread="+id; var gen = ''; if(canopen || canview ) { gen += HtmlGenerationUtils.popupLink( (cantakenow||!canview) ? link : link+"&viewonly=true", localized[canopen ? 0 : 1], "ImCenter"+id, username, 640, 480, null); } else { gen += '' + username + ''; } gen += ''; if( canopen ) { gen += ''; gen += HtmlGenerationUtils.popupLink( link, localized[0], "ImCenter"+id, ''+localized[0]+'', 640, 480, null); gen += ''; cellsCount++; } if( canview ) { gen += ''; gen += HtmlGenerationUtils.popupLink( link+"&viewonly=true", localized[1], "ImCenter"+id, ''+localized[1]+'', 640, 480, null); gen += ''; cellsCount++; } if( message != "" ) { gen += ''; gen += message.length > 30 ? message.substring(0,30) + '...' : message; gen += ''; } return HtmlGenerationUtils.generateOneRowTable(gen); }, banCell: function(id,banid){ return ''+ HtmlGenerationUtils.popupLink( webimRoot+'/operator/ban.php?'+(banid ? 'id='+banid : 'thread='+id), localized[2], "ban"+id, ''+localized[2]+'', 720, 480, null)+ ''; } }; Ajax.ThreadListUpdater = Class.create(); Class.inherit( Ajax.ThreadListUpdater, Ajax.Base, { initialize: function(_options) { this.setOptions(_options); this._options.updateParams = this.updateParams.bind(this); this._options.handleError = this.handleError.bind(this); this._options.updateContent = this.updateContent.bind(this); this._options.lastrevision = 0; this.threadTimers = new Object(); this.delta = 0; this.t = this._options.table; this.periodicalUpdater = new Ajax.PeriodicalUpdater(this._options); }, updateParams: function() { return "since=" + this._options.lastrevision + "&status=" + this._options.istatus + (this._options.showonline ? "&showonline=1" : ""); }, setStatus: function(msg) { this._options.status.innerHTML = msg; }, handleError: function(s) { this.setStatus( s ); }, updateThread: function(node) { var id, stateid, vstate, canview = false, canopen = false, canban = false, ban = null, banid = null; for( var i = 0; i < node.attributes.length; i++ ) { var attr = node.attributes[i]; if( attr.nodeName == "id" ) id = attr.nodeValue; else if( attr.nodeName == "stateid" ) stateid = attr.nodeValue; else if( attr.nodeName == "state" ) vstate = attr.nodeValue; else if( attr.nodeName == "canopen" ) canopen = true; else if( attr.nodeName == "canview" ) canview = true; else if( attr.nodeName == "canban" ) canban = true; else if( attr.nodeName == "ban" ) ban = attr.nodeValue; else if( attr.nodeName == "banid" ) banid = attr.nodeValue; } function setcell(_table, row,id,pcontent) { var cell = CommonUtils.getCell( id, row, _table ); if( cell ) cell.innerHTML = pcontent; } var row = CommonUtils.getRow("thr"+id, this.t); if( stateid == "closed" ) { if( row ) { this.t.deleteRow(row.rowIndex); } this.threadTimers[id] = null; return; } var vname = NodeUtils.getNodeValue(node,"name"); var vaddr = NodeUtils.getNodeValue(node,"addr"); var vtime = NodeUtils.getNodeValue(node,"time"); var agent = NodeUtils.getNodeValue(node,"agent"); var modified = NodeUtils.getNodeValue(node,"modified"); var message = NodeUtils.getNodeValue(node,"message"); var etc = ''+NodeUtils.getNodeValue(node,"useragent")+''; if(ban != null) { etc = ''+NodeUtils.getNodeValue(node,"reason")+''; } if(canban) { etc += HtmlGenerationUtils.banCell(id,banid); } etc = HtmlGenerationUtils.generateOneRowTable(etc); var startRow = CommonUtils.getRow("t"+stateid, this.t); var endRow = CommonUtils.getRow("t"+stateid+"end", this.t); if( row != null && (row.rowIndex <= startRow.rowIndex || row.rowIndex >= endRow.rowIndex ) ) { this.t.deleteRow(row.rowIndex); this.threadTimers[id] = null; row = null; } if( row == null ) { row = this.t.insertRow(startRow.rowIndex+1); row.className = (ban == "blocked" && stateid != "chat") ? "ban" : "in"+stateid; row.id = "thr"+id; this.threadTimers[id] = new Array(vtime,modified,stateid); CommonUtils.insertCell(row, "name", "visitor", null, null, HtmlGenerationUtils.viewOpenCell(vname,this._options.agentservl,id,canview,canopen,ban,message,stateid!='chat')); CommonUtils.insertCell(row, "contid", "visitor", "center", null, vaddr ); CommonUtils.insertCell(row, "state", "visitor", "center", null, vstate ); CommonUtils.insertCell(row, "op", "visitor", "center", null, agent ); CommonUtils.insertCell(row, "time", "visitor", "center", null, this.getTimeSince(vtime) ); CommonUtils.insertCell(row, "wait", "visitor", "center", null, (stateid!='chat' ? this.getTimeSince(modified) : '-') ); CommonUtils.insertCell(row, "etc", "visitor", "center", null, etc ); if( stateid == 'wait' || stateid == 'prio' ) return true; } else { this.threadTimers[id] = new Array(vtime,modified,stateid); row.className = (ban == "blocked" && stateid != "chat") ? "ban" : "in"+stateid; setcell(this.t, row,"name",HtmlGenerationUtils.viewOpenCell(vname,this._options.agentservl,id,canview,canopen,ban,message,stateid!='chat')); setcell(this.t, row,"contid",vaddr); setcell(this.t, row,"state",vstate); setcell(this.t, row,"op",agent); setcell(this.t, row,"time",this.getTimeSince(vtime)); setcell(this.t, row,"wait",(stateid!='chat' ? this.getTimeSince(modified) : '-')); setcell(this.t, row,"etc",etc); } return false; }, updateQueueMessages: function() { function queueNotEmpty(t,id) { var startRow = $(id); var endRow = $(id+"end"); if( startRow == null || endRow == null ) { return false; } return startRow.rowIndex+1 < endRow.rowIndex; } var _status = $("statustd"); if( _status) { var notempty = queueNotEmpty(this.t, "twait") || queueNotEmpty(this.t, "tprio") || queueNotEmpty(this.t, "tchat"); _status.innerHTML = notempty ? "" : this._options.noclients; _status.height = notempty ? 5 : 30; } }, getTimeSince: function(srvtime) { var secs = Math.floor(((new Date()).getTime()-srvtime-this.delta)/1000); var minutes = Math.floor(secs/60); var prefix = ""; secs = secs % 60; if( secs < 10 ) secs = "0" + secs; if( minutes >= 60 ) { var hours = Math.floor(minutes/60); minutes = minutes % 60; if( minutes < 10 ) minutes = "0" + minutes; prefix = hours + ":"; } return prefix + minutes+":"+secs; }, updateTimers: function() { for (var i in this.threadTimers) { if (this.threadTimers[i] != null) { var value = this.threadTimers[i]; var row = CommonUtils.getRow("thr"+i, this.t); if( row != null ) { function setcell(_table, row,id,pcontent) { var cell = CommonUtils.getCell( id, row, _table ); if( cell ) cell.innerHTML = pcontent; } setcell(this.t, row,"time",this.getTimeSince(value[0])); setcell(this.t, row,"wait",(value[2]!='chat' ? this.getTimeSince(value[1]) : '-')); } } } }, updateThreads: function(root) { var newAdded = false; var _time = NodeUtils.getAttrValue(root, "time"); var _revision = NodeUtils.getAttrValue(root, "revision" ); if( _time ) this.delta = (new Date()).getTime() - _time; if( _revision ) this._options.lastrevision = _revision; for( var i = 0; i < root.childNodes.length; i++ ) { var node = root.childNodes[i]; if( node.tagName == 'thread' ) if( this.updateThread(node) ) newAdded = true; } this.updateQueueMessages(); this.updateTimers(); this.setStatus(this._options.istatus ? "Away" : "Up to date"); if( newAdded ) { playSound(webimRoot+'/sounds/new_user.wav'); window.focus(); if(updaterOptions.showpopup) { alert(localized[5]); } } }, updateOperators: function(root) { var div = $('onlineoperators'); if (!div) return; var names = []; for( var i = 0; i < root.childNodes.length; i++ ) { var node = root.childNodes[i]; if(node.tagName != 'operator') continue; var name = NodeUtils.getAttrValue(node, 'name'); var isAway = NodeUtils.getAttrValue(node, 'away') != null; names[names.length] = ''+localized[1]+' '+ name; } div.innerHTML = names.join(', '); }, updateContent: function(root) { if( root.tagName == 'update' ) { for( var i = 0; i < root.childNodes.length; i++ ) { var node = root.childNodes[i]; if (node.tagName == 'threads') { this.updateThreads(node); } else if (node.tagName == 'operators') { this.updateOperators(node); } } } else if( root.tagName == 'error' ) { this.setStatus(NodeUtils.getNodeValue(root,"descr") ); } else { this.setStatus( "reconnecting" ); } } }); function togglemenu() { if($("sidebar") && $("wcontent") && $("togglemenu")) { if($("wcontent").className == "contentnomenu") { $("sidebar").style.display = "block"; $("wcontent").className = "contentinner"; $("togglemenu").innerHTML = localized[4]; } else { $("sidebar").style.display = "none"; $("wcontent").className = "contentnomenu"; $("togglemenu").innerHTML = localized[3]; } } } var webimRoot = ""; Behaviour.register({ '#togglemenu' : function(el) { el.onclick = function() { togglemenu(); }; } }); EventHelper.register(window, 'onload', function(){ webimRoot = updaterOptions.wroot; new Ajax.ThreadListUpdater(({table:$("threadlist"),status:$("connstatus"),istatus:0}).extend(updaterOptions || {})); if(!updaterOptions.havemenu) { togglemenu(); } });