mirror of
https://github.com/Mibew/mibew.git
synced 2024-11-15 16:44:11 +03:00
Refactor and format JavaScript chat code
This commit is contained in:
parent
72d0c3b0a4
commit
727625dfc8
@ -5,20 +5,21 @@
|
||||
Copyright (c) 2005-2011 Mibew Messenger Community
|
||||
License: http://mibew.org/license.php
|
||||
*/
|
||||
var FrameUtils={getDocument:function(a){return a.contentDocument?a.contentDocument:a.contentWindow?a.contentWindow.document:a.document?a.document:null},initFrame:function(a){var b=this.getDocument(a);b.open();b.write("<html><head>");b.write('<link rel="stylesheet" type="text/css" media="all" href="'+Chat.cssfile+'">');b.write("</head><body bgcolor='#FFFFFF' text='#000000' link='#C28400' vlink='#C28400' alink='#C28400'>");b.write("<table width='100%' cellspacing='0' cellpadding='0' border='0'><tr><td valign='top' class='message' id='content'></td></tr></table><a id='bottom' name='bottom'></a>");
|
||||
var FrameUtils={options:{},getDocument:function(a){return a.contentDocument?a.contentDocument:a.contentWindow?a.contentWindow.document:a.document?a.document:null},initFrame:function(a){var b=this.getDocument(a);b.open();b.write("<html><head>");this.options.cssfile&&b.write('<link rel="stylesheet" type="text/css" media="all" href="'+this.options.cssfile+'">');b.write("</head><body bgcolor='#FFFFFF' text='#000000' link='#C28400' vlink='#C28400' alink='#C28400'>");b.write("<table width='100%' cellspacing='0' cellpadding='0' border='0'><tr><td valign='top' class='message' id='content'></td></tr></table><a id='bottom' name='bottom'></a>");
|
||||
b.write("</body></html>");b.close();a.onload=function(){a.myHtml&&(FrameUtils.getDocument(a).getElementById("content").innerHTML+=a.myHtml,FrameUtils.scrollDown(a))}},insertIntoFrame:function(a,b){var c=this.getDocument(a).getElementById("content");null==c?(a.myHtml||(a.myHtml=""),a.myHtml+=b):c.innerHTML+=b},scrollDown:function(a){var b=this.getDocument(a).getElementById("bottom");if("opera"==myAgent)try{a.contentWindow.scrollTo(0,this.getDocument(a).getElementById("content").clientHeight)}catch(c){}b&&
|
||||
b.scrollIntoView(!1)}};ChatThreadUpdater=Class.create();
|
||||
ChatThreadUpdater.prototype={initialize:function(a,b,c){this._options=c;this.thread=b;this.chatServer=a;this.focused=this.skipNextsound=this.cansend=!0;this.ownThread=null!=this._options.message;FrameUtils.initFrame(this._options.container);this._options.message&&(this._options.message.onkeydown=this.handleKeyDown.bind(this),this._options.message.onfocus=function(){this.focused=!0}.bind(this),this._options.message.onblur=function(){this.focused=!1}.bind(this));this.chatServer.callFunctionsPeriodically(this.updateFunctionBuilder.bind(this),
|
||||
this.updateChatState.bind(this));this.chatServer.registerFunction("updateMessages",this.updateMessages.bind(this));this.chatServer.registerFunction("setupAvatar",this.setupAvatar.bind(this));this.chatServer.runUpdater()},handleException:function(){this.setStatus("offline, reconnecting");this.enableInput(!0)},handleTimeout:function(){this.setStatus("timeout, reconnecting");this.enableInput(!0)},enableInput:function(a){this._options.message&&(this._options.message.disabled=!a)},refresh:function(){this.chatServer.restartUpdater()},
|
||||
postMessage:function(a){""!=a&&this.cansend&&(this.cansend=!1,this.skipNextsound=!0,"opera"!=myRealAgent&&this.enableInput(!1),this.chatServer.callFunctions([{"function":"post",arguments:{references:{},"return":{},message:a,threadId:this.thread.threadid,token:this.thread.token,user:this.thread.user}}],function(){this.enableInput(!0);this.cansend=!0;this.skipNextsound=!1;this._options.message&&(this._options.message.value="",this._options.message.focus())}.bind(this),!0))},changeName:function(a){this.skipNextsound=
|
||||
!0;this.chatServer.callFunctions([{"function":"rename",arguments:{references:{},"return":{},threadId:this.thread.threadid,token:this.thread.token,name:a}}],function(a){a.errorCode&&this.handleError(a,"cannot rename")}.bind(this),!0)},closeThread:function(){(!this._options.localizedStrings.closeConfirmation||confirm(this._options.localizedStrings.closeConfirmation))&&this.chatServer.callFunctions([{"function":"close",arguments:{references:{},"return":{closed:"closed"},threadId:this.thread.threadid,
|
||||
token:this.thread.token,lastId:this.thread.lastid,user:this.thread.user}}],this.onThreadClosed.bind(this),!0)},onThreadClosed:function(a){a.closed?window.close():this.handleError(a,"cannot close")},processMessage:function(a,b){FrameUtils.insertIntoFrame(a,b)},showTyping:function(a){$("typingdiv")&&($("typingdiv").style.display=a?"inline":"none")},setupAvatar:function(a){this._options.avatar&&this.thread.user&&(this._options.avatar.innerHTML=""!=a.imageLink?'<img src="'+this._options.webimRoot+'/images/free.gif" width="7" height="1" border="0" alt="" /><img src="'+
|
||||
a.imageLink+'" border="0" alt=""/>':"")},updateMessages:function(a){a.lastId&&(this.thread.lastid=a.lastId);for(var b=0;b<a.messages.length;b++)this.processMessage(this._options.container,a.messages[b]);this.clearStatus();0<a.messages.length&&(FrameUtils.scrollDown(this._options.container),this.skipNextsound||(a=$("soundimg"),(null==a||a.className.match(/\bisound\b/))&&playSound(this._options.webimRoot+"/sounds/new_message.wav")),this.focused||window.focus());this.skipNextsound=!1},updateFunctionBuilder:function(){return[{"function":"update",
|
||||
arguments:{"return":{typing:"typing",canPost:"canPost"},references:{},threadId:this.thread.threadid,token:this.thread.token,lastId:this.thread.lastid,typed:this._options.message&&""!=this._options.message.value,user:this.thread.user}}]},updateChatState:function(a){if(a.errorCode)this.handleError(a,"refresh failed");else if("undefined"!=typeof a.typing&&this.showTyping(a.typing),"undefined"!=typeof a.canPost&&(a.canPost&&!this.ownThread||this.ownThread&&!a.canPost))window.location.href=window.location.href},
|
||||
isSendkey:function(a,b){return 13==b&&(a||this._options.ignorectrl)||10==b},handleKeyDown:function(a){a?(ctrl=a.ctrlKey,a=a.which):(a=event.keyCode,ctrl=event.ctrlKey);return this._options.message&&this.isSendkey(ctrl,a)?(a=this._options.message.value,this._options.ignorectrl&&(a=a.replace(/[\r\n]+$/,"")),this.postMessage(a),!1):!0},handleError:function(a){a.errorCode?this.setStatus(a.errorMessage):this.setStatus("reconnecting")},showStatusDiv:function(a){$("engineinfo")&&($("engineinfo").style.display=
|
||||
"inline",$("engineinfo").innerHTML=a)},setStatus:function(a){this.statusTimeout&&clearTimeout(this.statusTimeout);this.showStatusDiv(a);this.statusTimeout=setTimeout(this.clearStatus.bind(this),4E3)},clearStatus:function(){$("engineinfo").style.display="none"}};
|
||||
var Chat={threadUpdater:{},applyName:function(){Chat.threadUpdater.changeName($("uname").value);$("changename1").style.display="none";$("changename2").style.display="inline";$("unamelink").innerHTML=htmlescape($("uname").value)},showNameField:function(){$("changename1").style.display="inline";$("changename2").style.display="none"}};
|
||||
Behaviour.register({"#postmessage a":function(a){a.onclick=function(){var a=$("msgwnd");a&&Chat.threadUpdater.postMessage(a.value)}},"select#predefined":function(a){a.onchange=function(){var a=$("msgwnd");0!=this.selectedIndex&&(a.value=Chat.predefinedAnswers[this.selectedIndex-1]);this.selectedIndex=0;a.focus()}},"div#changename2 a":function(a){a.onclick=function(){Chat.showNameField();return!1}},"div#changename1 a":function(a){a.onclick=function(){Chat.applyName();return!1}},"div#changename1 input#uname":function(a){a.onkeydown=
|
||||
function(a){13==(a||event).keyCode&&Chat.applyName()}},"a#refresh":function(a){a.onclick=function(){Chat.threadUpdater.refresh()}},"a#togglesound":function(a){a.onclick=function(){var a=$("soundimg");a&&(a.className=a.className.match(/\bisound\b/)?"tplimage inosound":"tplimage isound",(a=$("msgwnd"))&&a.focus())}},"a.closethread":function(a){a.onclick=function(){Chat.threadUpdater.closeThread()}}});var pluginManager=new PluginManager;
|
||||
EventHelper.register(window,"onload",function(){var a=new ChatServer(chatParams.serverParams),b=new Thread(chatParams.threadParams);chatParams.initPlugins(pluginManager,b,a);Chat.cssfile=chatParams.cssfile;Chat.predefinedAnswers=chatParams.predefinedAnswers||[];Chat.localizedStrings=chatParams.localizedStrings;Chat.threadUpdater=new ChatThreadUpdater(a,b,{ignorectrl:-1,container:"safari"==myRealAgent?self.frames[0]:$("chatwnd"),avatar:$("avatarwnd"),message:$("msgwnd")}.extend(chatParams.threadUpdaterParams||
|
||||
{}))});
|
||||
b.scrollIntoView(!1)}};ChatView=Class.create();
|
||||
ChatView.prototype={statusTimeout:null,localizedStrings:{},predefinedAnswers:[],messageContainer:null,initialize:function(a,b){this.localizedStrings=a||{};this.predefinedAnswers=b||[];this.messageContainer="safari"==myRealAgent?self.frames[0]:$("chatwnd");FrameUtils.initFrame(this.messageContainer)},getLocaleString:function(a){return"undefined"==typeof this.localizedStrings[a]?!1:this.localizedStrings[a]},enableInput:function(a){var b=$("msgwnd");b&&(b.disabled=!a)},clearInput:function(){var a=$("msgwnd");
|
||||
a&&(a.value="",a.focus())},showStatusDiv:function(a){$("engineinfo")&&($("engineinfo").style.display="inline",$("engineinfo").innerHTML=a)},setStatus:function(a){this.statusTimeout&&clearTimeout(this.statusTimeout);this.showStatusDiv(a);this.statusTimeout=setTimeout(this.clearStatus.bind(this),4E3)},clearStatus:function(){$("engineinfo").style.display="none"},showTyping:function(a){$("typingdiv")&&($("typingdiv").style.display=a?"inline":"none")},updateAvatar:function(a,b){var c="";""!=b&&(c='<img src="'+
|
||||
a+'/images/free.gif" width="7" height="1" border="0" alt="" /><img src="'+b+'" border="0" alt=""/>');$("avatarwnd").innerHTML=c},displayMessages:function(a){for(var b=0;b<a.length;b++)this.outputMessage(a[b]);0<a.length&&FrameUtils.scrollDown(this.messageContainer)},outputMessage:function(a){FrameUtils.insertIntoFrame(this.messageContainer,a)},showNameField:function(){$("changename1").style.display="inline";$("changename2").style.display="none"},hideNameField:function(){$("changename1").style.display=
|
||||
"none";$("changename2").style.display="inline"},updateUserName:function(a){$("unamelink").innerHTML=htmlescape(a)},changeSoundButtonState:function(a){$("soundimg").className=a?"tplimage isound":"tplimage inosound";(a=$("msgwnd"))&&a.focus()},displayPredefinedAnswer:function(a){var b=$("msgwnd");b.value=this.predefinedAnswers[a];b.focus()},resetSelectedIndex:function(a){a.selectedIndex=0}};ChatController=Class.create();
|
||||
ChatController.prototype={options:{},thread:null,server:null,view:null,cansend:!0,skipNextSound:!0,focused:!0,message:null,ownThread:null,initialize:function(a,b,c,d){this.options=d;this.thread=c;this.server=a;this.view=b;this.message=$("msgwnd");this.ownThread=null!=this.message;this.message&&(this.message.onkeydown=this.handleKeyDown.bind(this),this.message.onfocus=function(){this.focused=!0}.bind(this),this.message.onblur=function(){this.focused=!1}.bind(this));this.server.callFunctionsPeriodically(this.updateFunctionBuilder.bind(this),
|
||||
this.updateChatState.bind(this));this.server.registerFunction("updateMessages",this.updateMessages.bind(this));this.server.registerFunction("setupAvatar",this.setupAvatar.bind(this));this.server.runUpdater()},handleException:function(){this.view.setStatus("offline, reconnecting");this.view.enableInput(!0)},handleTimeout:function(){this.view.setStatus("timeout, reconnecting");this.view.enableInput(!0)},refresh:function(){this.server.restartUpdater()},postMessage:function(a){""!=a&&this.cansend&&(this.cansend=
|
||||
!1,this.skipNextSound=!0,"opera"!=myRealAgent&&this.view.enableInput(!1),this.server.callFunctions([{"function":"post",arguments:{references:{},"return":{},message:a,threadId:this.thread.threadid,token:this.thread.token,user:this.thread.user}}],function(){this.view.enableInput(!0);this.cansend=!0;this.view.clearInput()}.bind(this),!0))},changeName:function(a){this.skipNextSound=!0;this.server.callFunctions([{"function":"rename",arguments:{references:{},"return":{},threadId:this.thread.threadid,token:this.thread.token,
|
||||
name:a}}],function(a){a.errorCode&&this.handleError(a,"cannot rename")}.bind(this),!0)},closeThread:function(){(!this.view.getLocaleString("closeConfirmation")||confirm(this.view.getLocaleString("closeConfirmation")))&&this.server.callFunctions([{"function":"close",arguments:{references:{},"return":{closed:"closed"},threadId:this.thread.threadid,token:this.thread.token,lastId:this.thread.lastid,user:this.thread.user}}],this.onThreadClosed.bind(this),!0)},onThreadClosed:function(a){a.closed?window.close():
|
||||
this.handleError(a,"cannot close")},setupAvatar:function(a){$("avatarwnd")&&this.thread.user&&this.view.updateAvatar(this.options.webimRoot,a.imageLink)},updateMessages:function(a){a.lastId&&(this.thread.lastid=a.lastId);this.view.displayMessages(a.messages);this.view.clearStatus();0<a.messages.length&&(this.skipNextSound||(a=$("soundimg"),(null==a||a.className.match(/\bisound\b/))&&playSound(this.options.webimRoot+"/sounds/new_message.wav")),this.focused||window.focus());this.skipNextSound=!1},updateFunctionBuilder:function(){return[{"function":"update",
|
||||
arguments:{"return":{typing:"typing",canPost:"canPost"},references:{},threadId:this.thread.threadid,token:this.thread.token,lastId:this.thread.lastid,typed:this.message&&""!=this.message.value,user:this.thread.user}}]},updateChatState:function(a){if(a.errorCode)this.handleError(a,"refresh failed");else if("undefined"!=typeof a.typing&&this.view.showTyping(a.typing),"undefined"!=typeof a.canPost&&(a.canPost&&!this.ownThread||this.ownThread&&!a.canPost))window.location.href=window.location.href},isSendkey:function(a,
|
||||
b){return 13==b&&(a||this.options.ignorectrl)||10==b},handleKeyDown:function(a){a?(ctrl=a.ctrlKey,a=a.which):(a=event.keyCode,ctrl=event.ctrlKey);return this.message&&this.isSendkey(ctrl,a)?(a=this.message.value,this.options.ignorectrl&&(a=a.replace(/[\r\n]+$/,"")),this.postMessage(a),!1):!0},handleError:function(a){a.errorCode?this.view.setStatus(a.errorMessage):this.view.setStatus("reconnecting")},applyName:function(){this.changeName($("uname").value);this.view.hideNameField();this.view.updateUserName($("uname").value)},
|
||||
showNameField:function(){this.view.showNameField()},selectPredefinedAnswer:function(a){var b=a.selectedIndex;0!=b&&(this.view.displayPredefinedAnswer(b-1),this.view.resetSelect(a))},toggleSound:function(){var a=$("soundimg");a&&(a.className.match(/\bisound\b/)?this.view.changeSoundButtonState(!1):this.view.changeSoundButtonState(!0))}};
|
||||
Behaviour.register({"#postmessage a":function(a){a.onclick=function(){var a=$("msgwnd");a&&chatController.postMessage(a.value)}},"select#predefined":function(a){a.onchange=function(){chatController.selectPredefinedAnswer(this)}},"div#changename2 a":function(a){a.onclick=function(){chatController.showNameField();return!1}},"div#changename1 a":function(a){a.onclick=function(){chatController.applyName();return!1}},"div#changename1 input#uname":function(a){a.onkeydown=function(a){13==(a||event).keyCode&&
|
||||
chatController.applyName()}},"a#refresh":function(a){a.onclick=function(){chatController.refresh()}},"a#togglesound":function(a){a.onclick=function(){chatController.toggleSound()}},"a.closethread":function(a){a.onclick=function(){chatController.closeThread()}}});var pluginManager=new PluginManager,chatController;
|
||||
EventHelper.register(window,"onload",function(){FrameUtils.options.cssfile=chatParams.cssfile;var a=new ChatServer(chatParams.serverParams),b=new Thread(chatParams.threadParams);chatParams.initPlugins(pluginManager,b,a);var c=new ChatView(chatParams.localizedStrings,chatParams.predefinedAnswers||[]);chatController=new ChatController(a,c,b,{ignorectrl:-1}.extend(chatParams.controllerParams||{}))});
|
@ -7,6 +7,9 @@
|
||||
*/
|
||||
|
||||
var FrameUtils = {
|
||||
|
||||
options: {},
|
||||
|
||||
getDocument: function(frm) {
|
||||
if (frm.contentDocument) {
|
||||
return frm.contentDocument;
|
||||
@ -23,7 +26,9 @@ var FrameUtils = {
|
||||
var doc = this.getDocument(frm);
|
||||
doc.open();
|
||||
doc.write("<html><head>");
|
||||
doc.write("<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\""+Chat.cssfile+"\">");
|
||||
if (this.options.cssfile) {
|
||||
doc.write("<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\""+this.options.cssfile+"\">");
|
||||
}
|
||||
doc.write("</head><body bgcolor='#FFFFFF' text='#000000' link='#C28400' vlink='#C28400' alink='#C28400'>");
|
||||
doc.write("<table width='100%' cellspacing='0' cellpadding='0' border='0'><tr><td valign='top' class='message' id='content'></td></tr></table><a id='bottom' name='bottom'></a>");
|
||||
doc.write("</body></html>");
|
||||
@ -39,7 +44,9 @@ var FrameUtils = {
|
||||
insertIntoFrame: function(frm, htmlcontent) {
|
||||
var vcontent = this.getDocument(frm).getElementById('content');
|
||||
if (vcontent == null) {
|
||||
if( !frm.myHtml ) frm.myHtml = "";
|
||||
if (!frm.myHtml) {
|
||||
frm.myHtml = "";
|
||||
}
|
||||
frm.myHtml += htmlcontent;
|
||||
} else {
|
||||
vcontent.innerHTML += htmlcontent;
|
||||
@ -59,118 +66,350 @@ var FrameUtils = {
|
||||
}
|
||||
};
|
||||
|
||||
ChatThreadUpdater = Class.create();
|
||||
ChatThreadUpdater.prototype = {
|
||||
ChatView = Class.create();
|
||||
ChatView.prototype = {
|
||||
/**
|
||||
* Create an instance of ChatThreadUpdater
|
||||
* @constructor
|
||||
* @param {ChatServer} chatServer An instance of ChatServer class
|
||||
* @param {Thread} thread Thread object
|
||||
* @param {Object} options Additional configuration options
|
||||
* @todo Add error handlers to chatServer
|
||||
* @todo Think about code format
|
||||
* Status timeout identifier
|
||||
* @type Number
|
||||
* @private
|
||||
*/
|
||||
initialize: function(chatServer, thread, options) {
|
||||
statusTimeout: null,
|
||||
|
||||
/**
|
||||
* Contains localized strings. Properties names are language key and
|
||||
* properties values are localized strings
|
||||
* @type Object
|
||||
*/
|
||||
localizedStrings: {},
|
||||
|
||||
/**
|
||||
* Contains predefined answers configurable from administrative interface
|
||||
* @type Array
|
||||
*/
|
||||
predefinedAnswers: [],
|
||||
|
||||
/**
|
||||
* Messages container DOM element
|
||||
* @type Object
|
||||
*/
|
||||
messageContainer: null,
|
||||
|
||||
/**
|
||||
* Create an instance of ChatView
|
||||
* @constructor
|
||||
*/
|
||||
initialize: function(localizedStrings, predefinedAnswers) {
|
||||
this.localizedStrings = localizedStrings || {};
|
||||
this.predefinedAnswers = predefinedAnswers || [];
|
||||
|
||||
this.messageContainer = (myRealAgent == 'safari')
|
||||
? self.frames[0]
|
||||
: $("chatwnd");
|
||||
FrameUtils.initFrame(this.messageContainer);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get localized string by language key
|
||||
* @param {String} key Language key
|
||||
* @returns {Boolean|String} Returns boolean FALSE if string with specified
|
||||
* key is undefined and localized string otherwise
|
||||
*/
|
||||
getLocaleString: function(key) {
|
||||
if (typeof this.localizedStrings[key] == 'undefined') {
|
||||
return false;
|
||||
}
|
||||
return this.localizedStrings[key];
|
||||
},
|
||||
|
||||
/**
|
||||
* Enables or disables input field
|
||||
* @param {Boolean} val Use boolean true for enable input and false
|
||||
* otherwise
|
||||
*/
|
||||
enableInput: function(val) {
|
||||
var message = $('msgwnd');
|
||||
if (message) {
|
||||
message.disabled = !val;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear message input element and set focus to it
|
||||
*/
|
||||
clearInput: function() {
|
||||
var message = $('msgwnd');
|
||||
if(message) {
|
||||
message.value = '';
|
||||
message.focus();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays status div and sets the status string into it
|
||||
* @param {String} k Status string
|
||||
*/
|
||||
showStatusDiv: function(k) {
|
||||
if ($("engineinfo")) {
|
||||
$("engineinfo").style.display = 'inline';
|
||||
$("engineinfo").innerHTML = k;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the status
|
||||
* @param {String} k Status string
|
||||
*/
|
||||
setStatus: function(k) {
|
||||
if (this.statusTimeout) {
|
||||
clearTimeout(this.statusTimeout);
|
||||
}
|
||||
this.showStatusDiv(k);
|
||||
this.statusTimeout = setTimeout(this.clearStatus.bind(this), 4000);
|
||||
},
|
||||
|
||||
/**
|
||||
* Hide the status string
|
||||
*/
|
||||
clearStatus: function() {
|
||||
$("engineinfo").style.display='none';
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays typing status
|
||||
* @param {Boolean} istyping Indicates the other side of conversation is
|
||||
* typing a message or not
|
||||
*/
|
||||
showTyping: function(istyping) {
|
||||
if( $("typingdiv") ) {
|
||||
$("typingdiv").style.display = istyping ? 'inline' : 'none';
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates operator's avatar
|
||||
* @param {String} root Base path
|
||||
* @param {String} imageLink New avatar URL
|
||||
*/
|
||||
updateAvatar: function(root, imageLink) {
|
||||
var avatar = "";
|
||||
if (imageLink != "") {
|
||||
avatar = '<img src="'+root+'/images/free.gif" width="7" height="1" border="0" alt="" />' +
|
||||
'<img src="'+imageLink+'" border="0" alt=""/>';
|
||||
}
|
||||
$("avatarwnd").innerHTML = avatar;
|
||||
},
|
||||
|
||||
/**
|
||||
* Display all messages at the message window
|
||||
* @param {Array} messages Messages array
|
||||
*/
|
||||
displayMessages: function(messages) {
|
||||
// Output messages
|
||||
for (var i = 0; i < messages.length; i++) {
|
||||
this.outputMessage(messages[i]);
|
||||
}
|
||||
// There are some new messages
|
||||
if (messages.length > 0) {
|
||||
FrameUtils.scrollDown(this.messageContainer);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Add message to the message window
|
||||
* @param {String} message HTML message to insert
|
||||
* @private
|
||||
*/
|
||||
outputMessage: function(message) {
|
||||
FrameUtils.insertIntoFrame(this.messageContainer, message);
|
||||
},
|
||||
|
||||
/**
|
||||
* Show new user name input
|
||||
*/
|
||||
showNameField: function() {
|
||||
$('changename1').style.display='inline';
|
||||
$('changename2').style.display='none';
|
||||
},
|
||||
|
||||
/**
|
||||
* Hide new user name input
|
||||
*/
|
||||
hideNameField: function() {
|
||||
$('changename1').style.display='none';
|
||||
$('changename2').style.display='inline';
|
||||
},
|
||||
|
||||
/**
|
||||
* Update user name in chat window
|
||||
* @param {String} name New user's name
|
||||
*/
|
||||
updateUserName: function(name) {
|
||||
$('unamelink').innerHTML = htmlescape(name);
|
||||
},
|
||||
|
||||
/**
|
||||
* Change sound button state.
|
||||
*
|
||||
* @param {Boolean} enable TRUE if sound enabled and FALSE otherwise
|
||||
*/
|
||||
changeSoundButtonState: function(enable) {
|
||||
var tsound = $('soundimg');
|
||||
if (enable) {
|
||||
tsound.className = "tplimage isound";
|
||||
} else {
|
||||
tsound.className = "tplimage inosound";
|
||||
}
|
||||
var messagePane = $('msgwnd');
|
||||
if(messagePane) {
|
||||
messagePane.focus();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Add predefined answer to message input element and set focus to it.
|
||||
*
|
||||
* @param {Number} answerIndex Index of predefined answer
|
||||
*/
|
||||
displayPredefinedAnswer: function(answerIndex) {
|
||||
var message = $('msgwnd');
|
||||
message.value = this.predefinedAnswers[answerIndex];
|
||||
message.focus();
|
||||
},
|
||||
|
||||
/**
|
||||
* Set selectedIndex property of the select box DOM element passed as
|
||||
* argument to zero.
|
||||
* @param {Object} elem Select box DOM element
|
||||
*/
|
||||
resetSelectedIndex: function(elem) {
|
||||
elem.selectedIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ChatController = Class.create();
|
||||
ChatController.prototype = {
|
||||
/**
|
||||
* Additional options
|
||||
* @type Object
|
||||
* @private
|
||||
*/
|
||||
this._options = options;
|
||||
options: {},
|
||||
|
||||
/**
|
||||
* An instance of the Thread class
|
||||
* @type Thread
|
||||
*/
|
||||
this.thread = thread;
|
||||
thread: null,
|
||||
|
||||
/**
|
||||
* An instance of the ChatServer class
|
||||
* @type ChatServer
|
||||
*/
|
||||
this.chatServer = chatServer;
|
||||
server: null,
|
||||
|
||||
/**
|
||||
* An instance of the ChatView class
|
||||
* @type ChatView
|
||||
*/
|
||||
view: null,
|
||||
|
||||
/**
|
||||
* Indicates if user can post messages
|
||||
* @type Boolean
|
||||
*/
|
||||
this.cansend = true;
|
||||
cansend: true,
|
||||
|
||||
/**
|
||||
* Indicates if next message's sound must be skipped
|
||||
* @type Boolean
|
||||
*/
|
||||
this.skipNextsound = true;
|
||||
skipNextSound: true,
|
||||
|
||||
/**
|
||||
* Indicates if message input area ihn focus
|
||||
* @type Boolean
|
||||
*/
|
||||
this.focused = true;
|
||||
focused: true,
|
||||
|
||||
/**
|
||||
* Message input DOM element
|
||||
* @type Object
|
||||
*/
|
||||
message: null,
|
||||
|
||||
/**
|
||||
* Indicates the thread belong to this operator
|
||||
* @type Boolean
|
||||
*/
|
||||
this.ownThread = this._options.message != null;
|
||||
ownThread: null,
|
||||
|
||||
FrameUtils.initFrame(this._options.container);
|
||||
if (this._options.message) {
|
||||
this._options.message.onkeydown = this.handleKeyDown.bind(this);
|
||||
this._options.message.onfocus = (function() {this.focused = true;}).bind(this);
|
||||
this._options.message.onblur = (function() {this.focused = false;}).bind(this);
|
||||
/**
|
||||
* Create an instance of ChatController
|
||||
* @constructor
|
||||
* @param {ChatServer} chatServer An instance of ChatServer class
|
||||
* @param {Thread} thread Thread object
|
||||
* @param {ChatView} chatView A Chat view object
|
||||
* @param {Object} options Additional configuration options
|
||||
* @todo Add error handlers to chatServer
|
||||
* @todo Think about code format
|
||||
*/
|
||||
initialize: function(chatServer, chatView, thread, options) {
|
||||
|
||||
this.options = options;
|
||||
this.thread = thread;
|
||||
this.server = chatServer;
|
||||
this.view = chatView;
|
||||
|
||||
this.message = $('msgwnd');
|
||||
|
||||
this.ownThread = this.message != null;
|
||||
|
||||
if (this.message) {
|
||||
this.message.onkeydown = this.handleKeyDown.bind(this);
|
||||
this.message.onfocus = (function() {this.focused = true;}).bind(this);
|
||||
this.message.onblur = (function() {this.focused = false;}).bind(this);
|
||||
}
|
||||
|
||||
// Add periodic functions
|
||||
this.chatServer.callFunctionsPeriodically(
|
||||
this.server.callFunctionsPeriodically(
|
||||
this.updateFunctionBuilder.bind(this),
|
||||
this.updateChatState.bind(this)
|
||||
);
|
||||
|
||||
// Register functions
|
||||
this.chatServer.registerFunction(
|
||||
this.server.registerFunction(
|
||||
'updateMessages',
|
||||
this.updateMessages.bind(this)
|
||||
);
|
||||
this.chatServer.registerFunction(
|
||||
this.server.registerFunction(
|
||||
'setupAvatar',
|
||||
this.setupAvatar.bind(this)
|
||||
);
|
||||
|
||||
this.chatServer.runUpdater();
|
||||
this.server.runUpdater();
|
||||
},
|
||||
|
||||
/**
|
||||
* Exception handler. Updates status message
|
||||
*/
|
||||
handleException: function(e) {
|
||||
this.setStatus("offline, reconnecting");
|
||||
this.enableInput(true);
|
||||
this.view.setStatus("offline, reconnecting");
|
||||
this.view.enableInput(true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Timeout handler. Updates status message
|
||||
*/
|
||||
handleTimeout: function() {
|
||||
this.setStatus("timeout, reconnecting");
|
||||
this.enableInput(true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Enables or disables input field
|
||||
* @param {Boolean} val Use boolean true for enable input and false otherwise
|
||||
*/
|
||||
enableInput: function(val) {
|
||||
if( this._options.message ) {
|
||||
this._options.message.disabled = !val;
|
||||
}
|
||||
this.view.setStatus("timeout, reconnecting");
|
||||
this.view.enableInput(true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Load new messages by restarting thread updater.
|
||||
*/
|
||||
refresh: function() {
|
||||
this.chatServer.restartUpdater();
|
||||
this.server.restartUpdater();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -185,13 +424,13 @@ ChatThreadUpdater.prototype = {
|
||||
// Disable message sending
|
||||
this.cansend = false;
|
||||
// Disable next sound
|
||||
this.skipNextsound = true;
|
||||
this.skipNextSound = true;
|
||||
// Disable input
|
||||
if(myRealAgent != 'opera') {
|
||||
this.enableInput(false);
|
||||
this.view.enableInput(false);
|
||||
}
|
||||
// Post message
|
||||
this.chatServer.callFunctions(
|
||||
this.server.callFunctions(
|
||||
[{
|
||||
"function": "post",
|
||||
"arguments": {
|
||||
@ -204,13 +443,9 @@ ChatThreadUpdater.prototype = {
|
||||
}
|
||||
}],
|
||||
(function(){
|
||||
this.enableInput(true);
|
||||
this.view.enableInput(true);
|
||||
this.cansend = true;
|
||||
this.skipNextsound = false;
|
||||
if(this._options.message) {
|
||||
this._options.message.value = '';
|
||||
this._options.message.focus();
|
||||
}
|
||||
this.view.clearInput();
|
||||
}).bind(this),
|
||||
true
|
||||
);
|
||||
@ -221,8 +456,8 @@ ChatThreadUpdater.prototype = {
|
||||
* @param {String} newname A new user name
|
||||
*/
|
||||
changeName: function(newname) {
|
||||
this.skipNextsound = true;
|
||||
this.chatServer.callFunctions(
|
||||
this.skipNextSound = true;
|
||||
this.server.callFunctions(
|
||||
[{
|
||||
"function": "rename",
|
||||
"arguments": {
|
||||
@ -247,13 +482,13 @@ ChatThreadUpdater.prototype = {
|
||||
*/
|
||||
closeThread: function() {
|
||||
// Show confirmation message if can
|
||||
if(this._options.localizedStrings.closeConfirmation){
|
||||
if(! confirm(this._options.localizedStrings.closeConfirmation)){
|
||||
if (this.view.getLocaleString('closeConfirmation')) {
|
||||
if (! confirm(this.view.getLocaleString('closeConfirmation'))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Send request
|
||||
this.chatServer.callFunctions(
|
||||
this.server.callFunctions(
|
||||
[{
|
||||
"function": "close",
|
||||
"arguments": {
|
||||
@ -283,43 +518,19 @@ ChatThreadUpdater.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Add message to the message window
|
||||
* @param {Object} _target Target DOM element
|
||||
* @param {String} message HTML message to insert
|
||||
*/
|
||||
processMessage: function(_target, message) {
|
||||
FrameUtils.insertIntoFrame(_target, message);
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays typing status
|
||||
* @param {Boolean} istyping Indicates the other side of conversation is
|
||||
* typing a message or not
|
||||
*/
|
||||
showTyping: function(istyping) {
|
||||
if( $("typingdiv") ) {
|
||||
$("typingdiv").style.display=istyping ? 'inline' : 'none';
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update operator's avatar
|
||||
* @param {Array} args Array of arguments passed from the core
|
||||
*/
|
||||
setupAvatar: function(args) {
|
||||
if (this._options.avatar && this.thread.user) {
|
||||
this._options.avatar.innerHTML = args.imageLink != ""
|
||||
? "<img src=\""+this._options.webimRoot+"/images/free.gif\" width=\"7\" height=\"1\" border=\"0\" alt=\"\" /><img src=\""
|
||||
+args.imageLink+ "\" border=\"0\" alt=\"\"/>"
|
||||
: "";
|
||||
if ($("avatarwnd") && this.thread.user) {
|
||||
this.view.updateAvatar(this.options.webimRoot, args.imageLink);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Add new messages to chat window
|
||||
* @param {Object} args object of function arguments passed from the server
|
||||
* @todo Fix skipNextSound
|
||||
*/
|
||||
updateMessages: function(args){
|
||||
// Update last message id
|
||||
@ -327,26 +538,22 @@ ChatThreadUpdater.prototype = {
|
||||
this.thread.lastid = args.lastId;
|
||||
}
|
||||
// Add messages
|
||||
for (var i = 0; i < args.messages.length; i++) {
|
||||
// TODO: Add template engine
|
||||
this.processMessage(this._options.container, args.messages[i]);
|
||||
}
|
||||
this.view.displayMessages(args.messages);
|
||||
// Clear status string
|
||||
this.clearStatus();
|
||||
this.view.clearStatus();
|
||||
// There are some new messages
|
||||
if (args.messages.length > 0) {
|
||||
FrameUtils.scrollDown(this._options.container);
|
||||
if (!this.skipNextsound) {
|
||||
if (!this.skipNextSound) {
|
||||
var tsound = $('soundimg');
|
||||
if (tsound == null || tsound.className.match(new RegExp("\\bisound\\b"))) {
|
||||
playSound(this._options.webimRoot+'/sounds/new_message.wav');
|
||||
playSound(this.options.webimRoot+'/sounds/new_message.wav');
|
||||
}
|
||||
}
|
||||
if (!this.focused) {
|
||||
window.focus();
|
||||
}
|
||||
}
|
||||
this.skipNextsound = false;
|
||||
this.skipNextSound = false;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -362,7 +569,7 @@ ChatThreadUpdater.prototype = {
|
||||
"threadId": this.thread.threadid,
|
||||
"token": this.thread.token,
|
||||
"lastId": this.thread.lastid,
|
||||
"typed": (this._options.message && this._options.message.value != ''),
|
||||
"typed": (this.message && this.message.value != ''),
|
||||
"user": this.thread.user
|
||||
}
|
||||
}
|
||||
@ -381,7 +588,7 @@ ChatThreadUpdater.prototype = {
|
||||
}
|
||||
// Update typing indicator
|
||||
if (typeof args.typing != 'undefined') {
|
||||
this.showTyping(args.typing);
|
||||
this.view.showTyping(args.typing);
|
||||
}
|
||||
|
||||
// Check if user can post messages
|
||||
@ -399,7 +606,7 @@ ChatThreadUpdater.prototype = {
|
||||
* @param {Number} key Key code
|
||||
*/
|
||||
isSendkey: function(ctrlpressed, key) {
|
||||
return ((key==13 && (ctrlpressed || this._options.ignorectrl)) || (key==10));
|
||||
return ((key==13 && (ctrlpressed || this.options.ignorectrl)) || (key==10));
|
||||
},
|
||||
|
||||
/**
|
||||
@ -408,10 +615,16 @@ ChatThreadUpdater.prototype = {
|
||||
* @param {Object} k Event object
|
||||
*/
|
||||
handleKeyDown: function(k) {
|
||||
if( k ){ctrl=k.ctrlKey;k=k.which;} else {k=event.keyCode;ctrl=event.ctrlKey;}
|
||||
if( this._options.message && this.isSendkey(ctrl, k) ) {
|
||||
var mmsg = this._options.message.value;
|
||||
if( this._options.ignorectrl ) {
|
||||
if (k) {
|
||||
ctrl=k.ctrlKey;
|
||||
k=k.which;
|
||||
} else {
|
||||
k=event.keyCode;
|
||||
ctrl=event.ctrlKey;
|
||||
}
|
||||
if (this.message && this.isSendkey(ctrl, k)) {
|
||||
var mmsg = this.message.value;
|
||||
if (this.options.ignorectrl) {
|
||||
mmsg = mmsg.replace(/[\r\n]+$/,'');
|
||||
}
|
||||
this.postMessage(mmsg);
|
||||
@ -423,149 +636,140 @@ ChatThreadUpdater.prototype = {
|
||||
/**
|
||||
* Update status message
|
||||
*
|
||||
* @param {Array} args Array of arguments. Must contain 'errorCode' and
|
||||
* @param {Object} args Array of arguments. Must contain 'errorCode' and
|
||||
* 'errorMessage' keys
|
||||
* @param {String} descr Error description
|
||||
*/
|
||||
handleError: function(args, descr) {
|
||||
if (args.errorCode) {
|
||||
this.setStatus(args.errorMessage);
|
||||
this.view.setStatus(args.errorMessage);
|
||||
} else {
|
||||
this.setStatus('reconnecting');
|
||||
this.view.setStatus('reconnecting');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays status div and sets the status string into it
|
||||
*
|
||||
* @param {String} k Status string
|
||||
* Apply new user's name
|
||||
*/
|
||||
showStatusDiv: function(k) {
|
||||
if( $("engineinfo") ) {
|
||||
$("engineinfo").style.display='inline';
|
||||
$("engineinfo").innerHTML = k;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the status
|
||||
*
|
||||
* @param {String} k Status string
|
||||
*/
|
||||
setStatus: function(k) {
|
||||
if( this.statusTimeout )
|
||||
clearTimeout(this.statusTimeout);
|
||||
this.showStatusDiv(k);
|
||||
this.statusTimeout = setTimeout(this.clearStatus.bind(this), 4000);
|
||||
},
|
||||
|
||||
/**
|
||||
* Hide the status string
|
||||
*/
|
||||
clearStatus: function() {
|
||||
$("engineinfo").style.display='none';
|
||||
}
|
||||
}
|
||||
|
||||
var Chat = {
|
||||
threadUpdater : {},
|
||||
|
||||
applyName: function() {
|
||||
Chat.threadUpdater.changeName($('uname').value);
|
||||
$('changename1').style.display='none';
|
||||
$('changename2').style.display='inline';
|
||||
$('unamelink').innerHTML = htmlescape($('uname').value);
|
||||
this.changeName($('uname').value);
|
||||
this.view.hideNameField();
|
||||
this.view.updateUserName($('uname').value);
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays field for new user's name
|
||||
*/
|
||||
showNameField: function() {
|
||||
$('changename1').style.display='inline';
|
||||
$('changename2').style.display='none';
|
||||
}
|
||||
};
|
||||
this.view.showNameField();
|
||||
},
|
||||
|
||||
Behaviour.register({
|
||||
'#postmessage a' : function(el) {
|
||||
el.onclick = function() {
|
||||
var message = $('msgwnd');
|
||||
if( message )
|
||||
Chat.threadUpdater.postMessage(message.value);
|
||||
};
|
||||
},
|
||||
'select#predefined' : function(el) {
|
||||
el.onchange = function() {
|
||||
var message = $('msgwnd');
|
||||
if(this.selectedIndex!=0) {
|
||||
message.value = Chat.predefinedAnswers[this.selectedIndex-1];
|
||||
/**
|
||||
* Predefined Answer select event handler.
|
||||
*
|
||||
* Add selected predefined answer to message input and reset predefined
|
||||
* answers select box.
|
||||
*
|
||||
* @param {Object} answerSelect Predefined answer DOM element
|
||||
*/
|
||||
selectPredefinedAnswer: function(answerSelect) {
|
||||
var index = answerSelect.selectedIndex;
|
||||
if(index != 0) {
|
||||
this.view.displayPredefinedAnswer(index-1);
|
||||
this.view.resetSelect(answerSelect);
|
||||
}
|
||||
this.selectedIndex = 0;
|
||||
message.focus();
|
||||
};
|
||||
},
|
||||
'div#changename2 a' : function(el) {
|
||||
el.onclick = function() {
|
||||
Chat.showNameField();
|
||||
return false;
|
||||
};
|
||||
},
|
||||
'div#changename1 a' : function(el) {
|
||||
el.onclick = function() {
|
||||
Chat.applyName();
|
||||
return false;
|
||||
};
|
||||
},
|
||||
'div#changename1 input#uname' : function(el) {
|
||||
el.onkeydown = function(e) {
|
||||
var ev = e || event;
|
||||
if( ev.keyCode == 13 ) {
|
||||
Chat.applyName();
|
||||
}
|
||||
};
|
||||
},
|
||||
'a#refresh' : function(el) {
|
||||
el.onclick = function() {
|
||||
Chat.threadUpdater.refresh();
|
||||
};
|
||||
},
|
||||
'a#togglesound' : function(el) {
|
||||
el.onclick = function() {
|
||||
|
||||
/**
|
||||
* Toggle sound button
|
||||
*/
|
||||
toggleSound: function() {
|
||||
var tsound = $('soundimg');
|
||||
if(!tsound) {
|
||||
return;
|
||||
}
|
||||
if(tsound.className.match(new RegExp("\\bisound\\b"))) {
|
||||
tsound.className = "tplimage inosound";
|
||||
this.view.changeSoundButtonState(false);
|
||||
} else {
|
||||
tsound.className = "tplimage isound";
|
||||
this.view.changeSoundButtonState(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Behaviour.register({
|
||||
'#postmessage a' : function(el) {
|
||||
el.onclick = function() {
|
||||
var message = $('msgwnd');
|
||||
if (message) {
|
||||
chatController.postMessage(message.value);
|
||||
}
|
||||
var messagePane = $('msgwnd');
|
||||
if(messagePane)
|
||||
messagePane.focus();
|
||||
};
|
||||
},
|
||||
|
||||
'select#predefined' : function(el) {
|
||||
el.onchange = function() {
|
||||
chatController.selectPredefinedAnswer(this);
|
||||
};
|
||||
},
|
||||
|
||||
'div#changename2 a' : function(el) {
|
||||
el.onclick = function() {
|
||||
chatController.showNameField();
|
||||
return false;
|
||||
};
|
||||
},
|
||||
|
||||
'div#changename1 a' : function(el) {
|
||||
el.onclick = function() {
|
||||
chatController.applyName();
|
||||
return false;
|
||||
};
|
||||
},
|
||||
|
||||
'div#changename1 input#uname' : function(el) {
|
||||
el.onkeydown = function(e) {
|
||||
var ev = e || event;
|
||||
if( ev.keyCode == 13 ) {
|
||||
chatController.applyName();
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
'a#refresh' : function(el) {
|
||||
el.onclick = function() {
|
||||
chatController.refresh();
|
||||
};
|
||||
},
|
||||
|
||||
'a#togglesound' : function(el) {
|
||||
el.onclick = function() {
|
||||
chatController.toggleSound();
|
||||
};
|
||||
},
|
||||
|
||||
'a.closethread' : function(el) {
|
||||
el.onclick = function() {
|
||||
Chat.threadUpdater.closeThread();
|
||||
chatController.closeThread();
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
var pluginManager = new PluginManager();
|
||||
var chatController;
|
||||
|
||||
EventHelper.register(window, 'onload', function(){
|
||||
FrameUtils.options.cssfile = chatParams.cssfile;
|
||||
var chatServer = new ChatServer(chatParams.serverParams);
|
||||
var thread = new Thread(chatParams.threadParams);
|
||||
chatParams.initPlugins(pluginManager, thread, chatServer);
|
||||
Chat.cssfile = chatParams.cssfile;
|
||||
Chat.predefinedAnswers = chatParams.predefinedAnswers || [];
|
||||
Chat.localizedStrings = chatParams.localizedStrings;
|
||||
Chat.threadUpdater = new ChatThreadUpdater(
|
||||
var chatView = new ChatView(
|
||||
chatParams.localizedStrings,
|
||||
chatParams.predefinedAnswers || []
|
||||
);
|
||||
chatController = new ChatController(
|
||||
chatServer,
|
||||
chatView,
|
||||
thread,
|
||||
{
|
||||
ignorectrl: -1,
|
||||
container: myRealAgent=='safari'?self.frames[0]:$("chatwnd"),
|
||||
avatar: $("avatarwnd"),
|
||||
message: $("msgwnd")
|
||||
}.extend(chatParams.threadUpdaterParams || {})
|
||||
{ignorectrl: -1}.extend(chatParams.controllerParams || {})
|
||||
);
|
||||
});
|
@ -15,6 +15,7 @@ ${page:additional_js}
|
||||
<script type="text/javascript" language="javascript"><!--
|
||||
var chatParams = {
|
||||
cssfile: "${tplroot}/chat.css",
|
||||
localizedStrings: {closeConfirmation:"${page:chat.close.confirmation}"},
|
||||
${if:agent}${if:canpost}
|
||||
predefinedAnswers: ${page:fullPredefinedAnswers},
|
||||
${endif:canpost}${endif:agent}
|
||||
@ -27,10 +28,9 @@ var chatParams = {
|
||||
servl: "${webimroot}/thread.php",
|
||||
requestsFrequency: ${page:frequency}
|
||||
},
|
||||
threadUpdaterParams: {
|
||||
controllerParams: {
|
||||
webimRoot: "${webimroot}",
|
||||
ignorectrl:${page:ignorectrl},
|
||||
localizedStrings: {closeConfirmation:"${page:chat.close.confirmation}"}
|
||||
ignorectrl:${page:ignorectrl}
|
||||
},
|
||||
initPlugins: function(pluginManager, thread, chatServer) {
|
||||
${page:js_plugins}
|
||||
|
@ -15,6 +15,7 @@ ${page:additional_js}
|
||||
<script type="text/javascript" language="javascript"><!--
|
||||
var chatParams = {
|
||||
cssfile: "${tplroot}/chat.css",
|
||||
localizedStrings: {closeConfirmation:"${page:chat.close.confirmation}"},
|
||||
${if:agent}${if:canpost}
|
||||
predefinedAnswers: ${page:fullPredefinedAnswers},
|
||||
${endif:canpost}${endif:agent}
|
||||
@ -27,10 +28,9 @@ var chatParams = {
|
||||
servl: "${webimroot}/thread.php",
|
||||
requestsFrequency: ${page:frequency}
|
||||
},
|
||||
threadUpdaterParams: {
|
||||
controllerParams: {
|
||||
webimRoot: "${webimroot}",
|
||||
ignorectrl:${page:ignorectrl},
|
||||
localizedStrings: {closeConfirmation:"${page:chat.close.confirmation}"}
|
||||
ignorectrl:${page:ignorectrl}
|
||||
},
|
||||
initPlugins: function(pluginManager, thread, chatServer) {
|
||||
${page:js_plugins}
|
||||
|
@ -17,6 +17,7 @@
|
||||
<!--
|
||||
var chatParams = {
|
||||
cssfile: "${tplroot}/chat.css",
|
||||
localizedStrings: {closeConfirmation:"${page:chat.close.confirmation}"},
|
||||
${if:agent}${if:canpost}
|
||||
predefinedAnswers: ${page:fullPredefinedAnswers},
|
||||
${endif:canpost}${endif:agent}
|
||||
@ -29,10 +30,9 @@
|
||||
servl: "${webimroot}/thread.php",
|
||||
requestsFrequency: ${page:frequency}
|
||||
},
|
||||
threadUpdaterParams: {
|
||||
controllerParams: {
|
||||
webimRoot: "${webimroot}",
|
||||
ignorectrl:${page:ignorectrl},
|
||||
localizedStrings: {closeConfirmation:"${page:chat.close.confirmation}"}
|
||||
ignorectrl:${page:ignorectrl}
|
||||
},
|
||||
initPlugins: function(pluginManager, thread, chatServer) {
|
||||
${page:js_plugins}
|
||||
|
@ -15,6 +15,7 @@ ${page:additional_js}
|
||||
<script type="text/javascript" language="javascript"><!--
|
||||
var chatParams = {
|
||||
cssfile: "${tplroot}/chat.css",
|
||||
localizedStrings: {closeConfirmation:"${page:chat.close.confirmation}"},
|
||||
${if:agent}${if:canpost}
|
||||
predefinedAnswers: ${page:fullPredefinedAnswers},
|
||||
${endif:canpost}${endif:agent}
|
||||
@ -27,10 +28,9 @@ var chatParams = {
|
||||
servl: "${webimroot}/thread.php",
|
||||
requestsFrequency: ${page:frequency}
|
||||
},
|
||||
threadUpdaterParams: {
|
||||
controllerParams: {
|
||||
webimRoot: "${webimroot}",
|
||||
ignorectrl:${page:ignorectrl},
|
||||
localizedStrings: {closeConfirmation:"${page:chat.close.confirmation}"}
|
||||
ignorectrl:${page:ignorectrl}
|
||||
},
|
||||
initPlugins: function(pluginManager, thread, chatServer) {
|
||||
${page:js_plugins}
|
||||
|
Loading…
Reference in New Issue
Block a user