Extend plugin system

Plugins can add custom CSS and JavaScript files to chat window and
implement JavaScript plugins
This commit is contained in:
Dmitriy Simushev 2012-10-04 09:28:12 +00:00
parent c61789c2d7
commit 5ff3a7656d
10 changed files with 123 additions and 6 deletions

View File

@ -175,6 +175,11 @@ $pparam = verifyparam( "act", "/^(mailthread)$/", "default");
if( $pparam == "mailthread" ) { if( $pparam == "mailthread" ) {
expand("styles/dialogs", getchatstyle(), "mail.tpl"); expand("styles/dialogs", getchatstyle(), "mail.tpl");
} else if( $level == "ajaxed" ) { } else if( $level == "ajaxed" ) {
// Load JavaScript plugins and JavaScripts, CSS files required by them
$page['additional_css'] = get_additional_css('chatWindow');
$page['additional_js'] = get_additional_js('chatWindow');
$page['js_plugins'] = get_js_plugins('chatWindow');
// Expand page
expand("styles/dialogs", getchatstyle(), "chat.tpl"); expand("styles/dialogs", getchatstyle(), "chat.tpl");
} else if( $level == "simple" ) { } else if( $level == "simple" ) {
expand("styles/dialogs", getchatstyle(), "chatsimple.tpl"); expand("styles/dialogs", getchatstyle(), "chatsimple.tpl");

View File

@ -26,5 +26,6 @@ arguments:{references:{},"return":{closed:"closed"},threadId:this.thread.threadi
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"}}; 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"}}; 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= 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()}}}); 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(){Chat.cssfile=chatParams.cssfile;Chat.predefinedAnswers=chatParams.predefinedAnswers||[];Chat.localizedStrings=chatParams.localizedStrings;Chat.threadUpdater=new ChatThreadUpdater(new ChatServer(chatParams.serverParams),chatParams.threadParams,{ignorectrl:-1,container:"safari"==myRealAgent?self.frames[0]:$("chatwnd"),avatar:$("avatarwnd"),message:$("msgwnd")}.extend(chatParams.threadUpdaterParams||{}))}); EventHelper.register(window,"onload",function(){var a=new ChatServer(chatParams.serverParams),b=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||
{}))});

View File

@ -927,13 +927,18 @@ Behaviour.register({
} }
}); });
var pluginManager = new PluginManager();
EventHelper.register(window, 'onload', function(){ EventHelper.register(window, 'onload', function(){
var chatServer = new ChatServer(chatParams.serverParams);
var thread = chatParams.threadParams;
chatParams.initPlugins(pluginManager, thread, chatServer);
Chat.cssfile = chatParams.cssfile; Chat.cssfile = chatParams.cssfile;
Chat.predefinedAnswers = chatParams.predefinedAnswers || []; Chat.predefinedAnswers = chatParams.predefinedAnswers || [];
Chat.localizedStrings = chatParams.localizedStrings; Chat.localizedStrings = chatParams.localizedStrings;
Chat.threadUpdater = new ChatThreadUpdater( Chat.threadUpdater = new ChatThreadUpdater(
new ChatServer(chatParams.serverParams), chatServer,
chatParams.threadParams, thread,
{ {
ignorectrl: -1, ignorectrl: -1,
container: myRealAgent=='safari'?self.frames[0]:$("chatwnd"), container: myRealAgent=='safari'?self.frames[0]:$("chatwnd"),

View File

@ -64,6 +64,81 @@ function topage($text)
return myiconv($webim_encoding, getoutputenc(), $text); return myiconv($webim_encoding, getoutputenc(), $text);
} }
/**
* Load additional CSS files, required by plugins, and build HTML code to include them
*
* @param string $page_name CSS files load to this page
* @return string HTML block of 'link' tags
*/
function get_additional_css($page_name) {
$method = $page_name . 'AddCss';
$plugins = PluginManager::getAllPlugins();
$result = array();
// Check all plugins
foreach ($plugins as $plugin) {
if (is_callable(array($plugin, $method))) {
// Try to invoke '<$page_name>AddCss' method
$css_list = $plugin->$method();
foreach ($css_list as $css) {
// Add script tag for each javascript file
$result[] = '<link rel="stylesheet" type="text/css" href="' . $css . '">';
}
}
}
return implode("\n", $result);
}
/**
* Load additional JavaScript files, required by plugins, and build HTML code to include them
*
* @param string $page_name JavaScript files load to this page
* @return string HTML block of 'script' tags
*/
function get_additional_js($page_name) {
$method = $page_name . 'AddJs';
$plugins = PluginManager::getAllPlugins();
$result = array();
// Check all plugins
foreach ($plugins as $plugin) {
if (is_callable(array($plugin, $method))) {
// Try to invoke '<$page_name>AddJs' method
$js_list = $plugin->$method();
foreach ($js_list as $js) {
// Add script tag for each javascript file
$result[] = '<script type="text/javascript" src="' . $js . '"></script>';
}
}
}
return implode("\n", $result);
}
/**
* Build Javascript code that initialize JavaScript plugins
*
* @param string $page_name Plugins initialize at this page
* @return string JavaScript initialization block
*/
function get_js_plugins($page_name) {
$method = $page_name . 'AddJsPlugins';
$plugins = PluginManager::getAllPlugins();
$result = array();
// Check all plugins
foreach ($plugins as $plugin) {
if (is_callable(array($plugin, $method))) {
// Try to invoke '<$page_name>AddJsPlugins' method
$js_plugins = $plugin->$method();
foreach ($js_plugins as $js_plugin) {
// Add plugin's initialization code
$constructor = $js_plugin['constructor'];
array_unshift($js_plugin['init_values'], 'thread', 'chatServer');
$init_values = implode(', ', $js_plugin['init_values']);
$result[] = "pluginManager.addPlugin('{$constructor}', new {$constructor}({$init_values}));";
}
}
}
return implode("\n", $result);
}
function no_field($key) function no_field($key)
{ {
return getlocal2("errors.required", array(getlocal($key))); return getlocal2("errors.required", array(getlocal($key)));

View File

@ -124,6 +124,11 @@ if ($pparam == "redirect") {
setup_redirect_links($threadid, $operator, $token); setup_redirect_links($threadid, $operator, $token);
expand("../styles/dialogs", getchatstyle(), "redirect.tpl"); expand("../styles/dialogs", getchatstyle(), "redirect.tpl");
} else { } else {
// Load JavaScript plugins and JavaScripts, CSS files required by them
$page['additional_css'] = get_additional_css('chatWindow');
$page['additional_js'] = get_additional_js('chatWindow');
$page['js_plugins'] = get_js_plugins('chatWindow');
// Expand page
expand("../styles/dialogs", getchatstyle(), "chat.tpl"); expand("../styles/dialogs", getchatstyle(), "chat.tpl");
} }

View File

@ -1 +1,4 @@
Deny from all Order Allow,Deny
<FilesMatch "\.(js|css|jpe?g|gif|png|bmp)$">
Allow from all
</FilesMatch>

View File

@ -4,8 +4,11 @@
<title>${msg:chat.window.title.agent}</title> <title>${msg:chat.window.title.agent}</title>
<link rel="shortcut icon" href="${webimroot}/images/favicon.ico" type="image/x-icon"> <link rel="shortcut icon" href="${webimroot}/images/favicon.ico" type="image/x-icon">
<link rel="stylesheet" type="text/css" href="${tplroot}/chat.css"> <link rel="stylesheet" type="text/css" href="${tplroot}/chat.css">
${page:additional_css}
${page:additional_js}
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/common.js"></script> <script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/common.js"></script>
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/mibewapi.js"></script> <script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/mibewapi.js"></script>
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/pluginmanager.js"></script>
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/json2.js"></script> <script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/json2.js"></script>
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/brws.js"></script> <script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/brws.js"></script>
<script type="text/javascript" language="javascript"><!-- <script type="text/javascript" language="javascript"><!--
@ -27,6 +30,9 @@ var chatParams = {
webimRoot: "${webimroot}", webimRoot: "${webimroot}",
ignorectrl:${page:ignorectrl}, ignorectrl:${page:ignorectrl},
localizedStrings: {closeConfirmation:"${page:chat.close.confirmation}"} localizedStrings: {closeConfirmation:"${page:chat.close.confirmation}"}
},
initPlugins: function(pluginManager, thread, chatServer) {
${page:js_plugins}
} }
} }
//--> //-->
@ -92,7 +98,6 @@ var chatParams = {
</head> </head>
<body bgcolor="#FFFFFF" text="#000000" link="#C28400" vlink="#C28400" alink="#C28400" style="margin:0px;"> <body bgcolor="#FFFFFF" text="#000000" link="#C28400" vlink="#C28400" alink="#C28400" style="margin:0px;">
<table width="100%" style="height:100%;" cellspacing="0" cellpadding="0" border="0"> <table width="100%" style="height:100%;" cellspacing="0" cellpadding="0" border="0">
<tr> <tr>
<td valign="top"> <td valign="top">

View File

@ -4,8 +4,11 @@
<title>${msg:chat.window.title.agent}</title> <title>${msg:chat.window.title.agent}</title>
<link rel="shortcut icon" href="${webimroot}/images/favicon.ico" type="image/x-icon"> <link rel="shortcut icon" href="${webimroot}/images/favicon.ico" type="image/x-icon">
<link rel="stylesheet" type="text/css" href="${tplroot}/chat.css"> <link rel="stylesheet" type="text/css" href="${tplroot}/chat.css">
${page:additional_css}
${page:additional_js}
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/common.js"></script> <script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/common.js"></script>
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/mibewapi.js"></script> <script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/mibewapi.js"></script>
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/pluginmanager.js"></script>
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/json2.js"></script> <script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/json2.js"></script>
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/brws.js"></script> <script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/brws.js"></script>
<script type="text/javascript" language="javascript"><!-- <script type="text/javascript" language="javascript"><!--
@ -27,6 +30,9 @@ var chatParams = {
webimRoot: "${webimroot}", webimRoot: "${webimroot}",
ignorectrl:${page:ignorectrl}, ignorectrl:${page:ignorectrl},
localizedStrings: {closeConfirmation:"${page:chat.close.confirmation}"} localizedStrings: {closeConfirmation:"${page:chat.close.confirmation}"}
},
initPlugins: function(pluginManager, thread, chatServer) {
${page:js_plugins}
} }
} }
//--> //-->

View File

@ -5,8 +5,11 @@
<title>${msg:chat.window.title.agent}</title> <title>${msg:chat.window.title.agent}</title>
<link rel="shortcut icon" href="${webimroot}/images/favicon.ico" type="image/x-icon" /> <link rel="shortcut icon" href="${webimroot}/images/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="${tplroot}/chat.css" media="all" /> <link rel="stylesheet" type="text/css" href="${tplroot}/chat.css" media="all" />
${page:additional_css}
${page:additional_js}
<script type="text/javascript" src="${webimroot}/js/${jsver}/common.js"></script> <script type="text/javascript" src="${webimroot}/js/${jsver}/common.js"></script>
<script type="text/javascript" src="${webimroot}/js/${jsver}/mibewapi.js"></script> <script type="text/javascript" src="${webimroot}/js/${jsver}/mibewapi.js"></script>
<script type="text/javascript" src="${webimroot}/js/${jsver}/pluginmanager.js"></script>
<script type="text/javascript" src="${webimroot}/js/${jsver}/json2.js"></script> <script type="text/javascript" src="${webimroot}/js/${jsver}/json2.js"></script>
<script type="text/javascript" src="${webimroot}/js/${jsver}/brws.js"></script> <script type="text/javascript" src="${webimroot}/js/${jsver}/brws.js"></script>
<script type="text/javascript"> <script type="text/javascript">
@ -29,6 +32,9 @@
webimRoot: "${webimroot}", webimRoot: "${webimroot}",
ignorectrl:${page:ignorectrl}, ignorectrl:${page:ignorectrl},
localizedStrings: {closeConfirmation:"${page:chat.close.confirmation}"} localizedStrings: {closeConfirmation:"${page:chat.close.confirmation}"}
},
initPlugins: function(pluginManager, thread, chatServer) {
${page:js_plugins}
} }
} }
var stxt = 10; var stxt = 10;

View File

@ -4,8 +4,11 @@
<title>${msg:chat.window.title.agent}</title> <title>${msg:chat.window.title.agent}</title>
<link rel="shortcut icon" href="${webimroot}/images/favicon.ico" type="image/x-icon"> <link rel="shortcut icon" href="${webimroot}/images/favicon.ico" type="image/x-icon">
<link rel="stylesheet" type="text/css" href="${tplroot}/chat.css"> <link rel="stylesheet" type="text/css" href="${tplroot}/chat.css">
${page:additional_css}
${page:additional_js}
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/common.js"></script> <script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/common.js"></script>
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/mibewapi.js"></script> <script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/mibewapi.js"></script>
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/pluginmanager.js"></script>
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/json2.js"></script> <script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/json2.js"></script>
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/brws.js"></script> <script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/brws.js"></script>
<script type="text/javascript" language="javascript"><!-- <script type="text/javascript" language="javascript"><!--
@ -27,6 +30,9 @@ var chatParams = {
webimRoot: "${webimroot}", webimRoot: "${webimroot}",
ignorectrl:${page:ignorectrl}, ignorectrl:${page:ignorectrl},
localizedStrings: {closeConfirmation:"${page:chat.close.confirmation}"} localizedStrings: {closeConfirmation:"${page:chat.close.confirmation}"}
},
initPlugins: function(pluginManager, thread, chatServer) {
${page:js_plugins}
} }
} }
//--> //-->