Use JavaScript templates for messages

This commit is contained in:
Dmitriy Simushev 2012-10-11 15:44:03 +00:00
parent 3f39164db1
commit 14eed1072d
31 changed files with 520 additions and 127 deletions

View File

@ -5,8 +5,8 @@
Copyright (c) 2005-2011 Mibew Messenger Community
License: http://mibew.org/license.php
*/
var chatController=null;
var chatController={};
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()}}});
EventHelper.register(window,"onload",function(){$LAB.setOptions({BasePath:chatParams.jsBasePath}).script("json2.js").wait().script("mibewapi.js").wait().script("chatserver.js").script("thread.js").script("pluginmanager.js").script("brws.js").wait().script("chatcontroller.js").script("chatview.js").wait(function(){FrameUtils.options.cssfile=chatParams.cssfile;var a=new ChatServer(chatParams.serverParams),c=new Thread(chatParams.threadParams),b=new PluginManager;chatParams.initPlugins(b,c,a);b=new ChatView(chatParams.localizedStrings,
chatParams.predefinedAnswers||[]);chatController=new ChatController(a,b,c,{ignorectrl:-1}.extend(chatParams.controllerParams||{}))})});
EventHelper.register(window,"onload",function(){$LAB.setOptions({BasePath:chatParams.jsBasePath}).script("json2.js").wait().script("mibewapi.js").wait().script("chatserver.js").script("thread.js").script("messageview.js").script("pluginmanager.js").script("brws.js").wait().script("chatcontroller.js").script("chatview.js").wait(function(){FrameUtils.options.cssfile=chatParams.cssfile;var a=new ChatServer(chatParams.serverParams),c=new Thread(chatParams.threadParams),b=new PluginManager;chatParams.initPlugins(b,
c,a);b=new ChatView(new MessageView,chatParams.localizedStrings||{},chatParams.predefinedAnswers||[]);chatController=new ChatController(a,b,c,{ignorectrl:-1}.extend(chatParams.controllerParams||{}))})});

View File

@ -8,7 +8,7 @@
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)}};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}};
ChatView.prototype={statusTimeout:null,localizedStrings:{},predefinedAnswers:[],messageContainer:null,messageView:null,initialize:function(a,b,c){this.localizedStrings=b||{};this.predefinedAnswers=c||[];this.messageView=a;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){a=this.messageView.themeMessage(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}};

View File

@ -0,0 +1,10 @@
/*
This file is part of Mibew Messenger project.
http://mibew.org
Copyright (c) 2005-2011 Mibew Messenger Community
License: http://mibew.org/license.php
*/
var MessageView=function(){var b={"<":"&lt;",">":"&gt;","&":"&amp;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},c=/[&<>'"`]/g;this.kindToString=function(a){return a==this.KIND_USER?"user":a==this.KIND_AGENT?"agent":a==this.KIND_FOR_AGENT?"hidden":a==this.KIND_INFO?"inf":a==this.KIND_CONN?"conn":a==this.KIND_EVENTS?"event":""};this.escapeString=function(a){return a.replace(c,function(a){return b[a]||"&amp;"})};this.themeMessage=function(a){if(!Handlebars.templates.message)throw Error("There is no template for message loaded!");
if(a.kind==this.KIND_AVATAR)throw Error("KIND_AVATAR message kind is deprecated at window!");a.allowFormating=a.kind!=this.KIND_USER&&a.kind!=this.KIND_AGENT;a.kindName=this.kindToString(a.kind);a.message=this.escapeString(a.message);return Handlebars.templates.message(a)}};MessageView.prototype.KIND_USER=1;MessageView.prototype.KIND_AGENT=2;MessageView.prototype.KIND_FOR_AGENT=3;MessageView.prototype.KIND_INFO=4;MessageView.prototype.KIND_CONN=5;MessageView.prototype.KIND_EVENTS=6;
MessageView.prototype.KIND_AVATAR=7;Handlebars.registerHelper("allowTags",function(b){b=b.replace(/&lt;(span|strong)&gt;(.*?)&lt;\/\1&gt;/g,"<$1>$2</$1>");b=b.replace(/&lt;span class=&quot;(.*?)&quot;&gt;(.*?)&lt;\/span&gt;/g,'<span class="$1">$2</span>');return new Handlebars.SafeString(b)});

View File

@ -5,4 +5,4 @@
Copyright (c) 2005-2011 Mibew Messenger Community
License: http://mibew.org/license.php
*/
var Thread=function(a){this.threadid=a.threadid||0;this.token=a.token||0;this.lastid=a.lastid||0;this.user=a.user||!1};Thread.prototype.KIND_USER=1;Thread.prototype.KIND_AGENT=2;Thread.prototype.KIND_FOR_AGENT=3;Thread.prototype.KIND_INFO=4;Thread.prototype.KIND_CONN=5;Thread.prototype.KIND_EVENTS=6;Thread.prototype.KIND_AVATAR=7;
var Thread=function(a){this.threadid=a.threadid||0;this.token=a.token||0;this.lastid=a.lastid||0;this.user=a.user||!1};

View File

@ -6,7 +6,7 @@
* License: http://mibew.org/license.php
*/
var chatController = null;
var chatController = {};
Behaviour.register({
'#postmessage a' : function(el) {
@ -73,6 +73,7 @@ EventHelper.register(window, 'onload', function(){
.script('mibewapi.js').wait()
.script('chatserver.js')
.script('thread.js')
.script('messageview.js')
.script('pluginmanager.js')
.script('brws.js').wait()
.script('chatcontroller.js')
@ -84,7 +85,8 @@ EventHelper.register(window, 'onload', function(){
var pluginManager = new PluginManager();
chatParams.initPlugins(pluginManager, thread, chatServer);
var chatView = new ChatView(
chatParams.localizedStrings,
new MessageView(),
chatParams.localizedStrings || {},
chatParams.predefinedAnswers || []
);
chatController = new ChatController(

View File

@ -94,14 +94,19 @@ ChatView.prototype = {
*/
messageContainer: null,
messageView: null,
/**
* Create an instance of ChatView
* @todo Document it!
* @constructor
*/
initialize: function(localizedStrings, predefinedAnswers) {
initialize: function(messageView, localizedStrings, predefinedAnswers) {
this.localizedStrings = localizedStrings || {};
this.predefinedAnswers = predefinedAnswers || [];
this.messageView = messageView;
this.messageContainer = (myRealAgent == 'safari')
? self.frames[0]
: $("chatwnd");
@ -220,7 +225,8 @@ ChatView.prototype = {
* @private
*/
outputMessage: function(message) {
FrameUtils.insertIntoFrame(this.messageContainer, message);
var themedMessage = this.messageView.themeMessage(message);
FrameUtils.insertIntoFrame(this.messageContainer, themedMessage);
},
/**

View File

@ -0,0 +1,151 @@
/**
* @preserve This file is part of Mibew Messenger project.
* http://mibew.org
*
* Copyright (c) 2005-2011 Mibew Messenger Community
* License: http://mibew.org/license.php
*/
var MessageView = function() {
/**
* List of replacements pairs
* @type Object
* @private
*/
var badCharList = {
"<": "&lt;",
">": "&gt;",
"&": "&amp;",
'"': "&quot;",
"'": "&#x27;",
"`": "&#x60;"
}
/**
* Regular expression for characters that must be replaced by HTML entities
* @type RegExp
* @private
*/
var badCharRegEx = /[&<>'"`]/g;
/**
* Retrun message kind shortening name corresponding to message kind code
*
* @param {Number} kind Message kind code
* @returns {String} Message kind shortening name
*/
this.kindToString = function(kind) {
if (kind == this.KIND_USER) {
return "user";
}
if (kind == this.KIND_AGENT) {
return "agent";
}
if (kind == this.KIND_FOR_AGENT) {
return "hidden";
}
if (kind == this.KIND_INFO) {
return "inf";
}
if (kind == this.KIND_CONN) {
return "conn";
}
if (kind == this.KIND_EVENTS) {
return "event";
}
return "";
}
/**
* Replace HTML special characters('<', '>', '&', "'", '"', '`') by
* corresponding HTML entities.
*
* @param {String} str Unescaped string
* @returns {String} Escaped string
*/
this.escapeString = function(str) {
return str.replace(
badCharRegEx,
function(chr) {
return badCharList[chr] || "&amp;";
}
);
}
/**
* Prepare message and substitute it into message's template
*
* @param {Object} msg Message object
* @returns {String} Rendered message
*/
this.themeMessage = function(msg) {
// Check template existance
if (! Handlebars.templates.message) {
throw new Error('There is no template for message loaded!');
}
// Check message kind
if (msg.kind == this.KIND_AVATAR) {
throw new Error('KIND_AVATAR message kind is deprecated at window!');
}
// Add message fields
msg.allowFormating = (msg.kind != this.KIND_USER && msg.kind != this.KIND_AGENT);
msg.kindName = this.kindToString(msg.kind);
msg.message = this.escapeString(msg.message);
// Theme message
return Handlebars.templates.message(msg);
}
}
/** Message kind constants */
/**
* Message sent by user.
*/
MessageView.prototype.KIND_USER = 1;
/**
* Message sent by operator
*/
MessageView.prototype.KIND_AGENT = 2;
/**
* Hidden system message to operator
*/
MessageView.prototype.KIND_FOR_AGENT = 3;
/**
* System messages for user and operator
*/
MessageView.prototype.KIND_INFO = 4;
/**
* Message for user if operator have connection problems
*/
MessageView.prototype.KIND_CONN = 5;
/**
* System message about some events (like rename).
*/
MessageView.prototype.KIND_EVENTS = 6;
/**
* Message with operators avatar
*
* This kind of message leaved only for compatibility with core
*/
MessageView.prototype.KIND_AVATAR = 7;
/** End of message kind constants */
/**
* Register 'allowTags' Handlebars helper.
*
* This helper unescape HTML entities for allowed (span and strong) tags.
*/
Handlebars.registerHelper('allowTags', function(text) {
var result = text;
result = result.replace(
/&lt;(span|strong)&gt;(.*?)&lt;\/\1&gt;/g,
'<$1>$2</$1>'
);
result = result.replace(
/&lt;span class=&quot;(.*?)&quot;&gt;(.*?)&lt;\/span&gt;/g,
'<span class="$1">$2</span>'
);
return new Handlebars.SafeString(result);
});

View File

@ -38,38 +38,3 @@ var Thread = function(options) {
*/
this.user = options.user || false;
}
/** Message kinds section */
/**
* Message sent by user
*/
Thread.prototype.KIND_USER = 1;
/**
* Message sent by operator
*/
Thread.prototype.KIND_AGENT = 2;
/**
* Hidden system message to operator
*/
Thread.prototype.KIND_FOR_AGENT = 3;
/**
* System messages for user and operator
*/
Thread.prototype.KIND_INFO = 4;
/**
* Message for user if operator have connection problems
*/
Thread.prototype.KIND_CONN = 5;
/**
* System message about some events (like rename).
*/
Thread.prototype.KIND_EVENTS = 6;
/**
* Message with operators avatar
*
* This kind of message leaved only for compatibility with core
*/
Thread.prototype.KIND_AVATAR = 7;
/** End of Message kinds section */

View File

@ -0,0 +1,55 @@
(function() {
var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
templates['message'] = template(function (Handlebars,depth0,helpers,partials,data) {
helpers = helpers || Handlebars.helpers;
var buffer = "", stack1, foundHelper, functionType="function", escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing, self=this;
function program1(depth0,data) {
var buffer = "", stack1, foundHelper;
buffer += "<span class='n";
foundHelper = helpers.kindName;
if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
else { stack1 = depth0.kindName; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
buffer += escapeExpression(stack1) + "'>";
foundHelper = helpers.name;
if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
else { stack1 = depth0.name; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
buffer += escapeExpression(stack1) + "</span>: ";
return buffer;}
function program3(depth0,data) {
var stack1, foundHelper;
stack1 = depth0.message;
foundHelper = helpers.apply;
stack1 = foundHelper ? foundHelper.call(depth0, stack1, "urlReplace, nl2br, allowTags", {hash:{}}) : helperMissing.call(depth0, "apply", stack1, "urlReplace, nl2br, allowTags", {hash:{}});
return escapeExpression(stack1);}
function program5(depth0,data) {
var stack1, foundHelper;
stack1 = depth0.message;
foundHelper = helpers.apply;
stack1 = foundHelper ? foundHelper.call(depth0, stack1, "urlReplace, nl2br", {hash:{}}) : helperMissing.call(depth0, "apply", stack1, "urlReplace, nl2br", {hash:{}});
return escapeExpression(stack1);}
buffer += "<span>";
stack1 = depth0.created;
foundHelper = helpers.formatTime;
stack1 = foundHelper ? foundHelper.call(depth0, stack1, {hash:{}}) : helperMissing.call(depth0, "formatTime", stack1, {hash:{}});
buffer += escapeExpression(stack1) + "</span> \r\n";
stack1 = depth0.name;
stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.noop,fn:self.program(1, program1, data)});
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "\r\n<span class='m";
foundHelper = helpers.kindName;
if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
else { stack1 = depth0.kindName; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
buffer += escapeExpression(stack1) + "'>";
stack1 = depth0.allowFormating;
stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.program(5, program5, data),fn:self.program(3, program3, data)});
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "</span><br/>";
return buffer;});
})();

View File

@ -0,0 +1 @@
Deny from all

View File

@ -0,0 +1,3 @@
<span>{{formatTime created}}</span>
{{#if name}}<span class='n{{kindName}}'>{{name}}</span>: {{/if}}
<span class='m{{kindName}}'>{{#if allowFormating}}{{apply message "urlReplace, nl2br, allowTags"}}{{else}}{{apply message "urlReplace, nl2br"}}{{/if}}</span><br/>

View File

@ -359,77 +359,6 @@ Class Thread {
return false;
}
/**
* Return message kind name corresponding to kind code
*
* @param int $message_kind Message kind. One of the Thread::KIND_* constants
* @return string kind's full name or its shortening
*/
public static function kindToString($message_kind) {
$kind_names = array(
Thread::KIND_USER => 'user',
Thread::KIND_AGENT => 'agent',
Thread::KIND_FOR_AGENT => 'hidden',
Thread::KIND_INFO => 'inf',
Thread::KIND_CONN => 'conn',
Thread::KIND_EVENTS => 'event',
Thread::KIND_AVATAR => 'avatar'
);
if (! array_key_exists($message_kind, $kind_names)) {
return '';
}
return $kind_names[$message_kind];
}
/**
* Theme message to display in chat window
*
* @param array $message Message array
* @return string Ready to display themed message
*/
public static function themeMessage($message) {
global $webim_encoding;
// No theming for avatars
if ($message['kind'] == Thread::KIND_AVATAR) {
return '';
}
// Prepare messages fields
$creation_date = date("H:i:s", $message['created']);
$kind_name = Thread::kindToString($message['kind']);
$sender_name = $message['name']
? "<span class='n{$kind_name}'>" . htmlspecialchars($message['name']) . "</span>: "
: '';
// Prepare message text
// Escape special chars
$text = htmlspecialchars($message['message']);
// Replace URL's by <a> tags
$text = preg_replace('/(https?|ftp):\/\/\S*/', '<a href="$0" target="_blank">$0</a>', $text);
// Add <br> tags instead of \n chars
$text = str_replace("\n", "<br/>", $text);
// Span and storng tags available for system messages
if ($message['kind'] != Thread::KIND_USER && $message['kind'] != Thread::KIND_AGENT) {
$text = preg_replace('/&lt;(span|strong)&gt;(.*)&lt;\/\1&gt;/U', '<$1>$2</$1>', $text);
$text = preg_replace(
'/&lt;span class=&quot;(.*)&quot;&gt;(.*)&lt;\/span&gt;/U',
'<span class="$1">$2</span>',
$text
);
}
// Build result message
$result = sprintf(
"<span>%s</span> %s<span class='m%s'>%s</span><br/>",
$creation_date,
$sender_name,
$kind_name,
$text
);
return myiconv($webim_encoding, "utf-8", $result);
}
/**
* Return next revision number (last revision number plus one)
*
@ -664,12 +593,14 @@ Class Thread {
/**
* Load messages from database corresponding to the thread those ID's more than $lastid
*
* @global $webim_encoding
* @param boolean $is_user Boolean TRUE if messages loads for user and boolean FALSE if they loads for operator.
* @param int $lastid ID of the last loaded message.
* @return array Array of messages
* @see Thread::postMessage()
*/
public function getMessages($is_user, &$last_id) {
global $webim_encoding;
$db = Database::getInstance();
@ -687,7 +618,10 @@ Class Thread {
array('return_rows' => Database::RETURN_ALL_ROWS)
);
foreach ($messages as $msg) {
foreach ($messages as $key => $msg) {
// Change message fields encoding
$messages[$key]['name'] = myiconv($webim_encoding, "utf-8", $msg['name']);
$messages[$key]['message'] = myiconv($webim_encoding, "utf-8", $msg['message']);
// Get last message ID
if ($msg['id'] > $last_id) {
$last_id = $msg['id'];

View File

@ -259,9 +259,6 @@ class ThreadProcessor extends RequestProcessor {
unset($messages[$key]);
continue;
}
// Theme message
$messages[$key] = Thread::themeMessage($msg);
}
// Send messages
$this->responses[] = array(

View File

@ -53,12 +53,12 @@ if (isset($_GET['threadid'])) {
// Build messages list
$lastid = -1;
$messages = $thread_info['thread']->getMessages(false, $lastid);
foreach ($messages as $msg) {
foreach ($messages as $key => $msg) {
if ($msg['kind'] == Thread::KIND_AVATAR) {
continue;
unset($messages[$key]);
}
$page['threadMessages'][] = Thread::themeMessage($msg);
}
$page['threadMessages'] = json_encode($messages);
}
prepare_menu($operator, false);

View File

@ -0,0 +1,55 @@
(function() {
var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
templates['message'] = template(function (Handlebars,depth0,helpers,partials,data) {
helpers = helpers || Handlebars.helpers;
var buffer = "", stack1, foundHelper, functionType="function", escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing, self=this;
function program1(depth0,data) {
var buffer = "", stack1, foundHelper;
buffer += "<span class='n";
foundHelper = helpers.kindName;
if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
else { stack1 = depth0.kindName; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
buffer += escapeExpression(stack1) + "'>";
foundHelper = helpers.name;
if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
else { stack1 = depth0.name; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
buffer += escapeExpression(stack1) + "</span>: ";
return buffer;}
function program3(depth0,data) {
var stack1, foundHelper;
stack1 = depth0.message;
foundHelper = helpers.apply;
stack1 = foundHelper ? foundHelper.call(depth0, stack1, "urlReplace, nl2br, allowTags", {hash:{}}) : helperMissing.call(depth0, "apply", stack1, "urlReplace, nl2br, allowTags", {hash:{}});
return escapeExpression(stack1);}
function program5(depth0,data) {
var stack1, foundHelper;
stack1 = depth0.message;
foundHelper = helpers.apply;
stack1 = foundHelper ? foundHelper.call(depth0, stack1, "urlReplace, nl2br", {hash:{}}) : helperMissing.call(depth0, "apply", stack1, "urlReplace, nl2br", {hash:{}});
return escapeExpression(stack1);}
buffer += "<span>";
stack1 = depth0.created;
foundHelper = helpers.formatTime;
stack1 = foundHelper ? foundHelper.call(depth0, stack1, {hash:{}}) : helperMissing.call(depth0, "formatTime", stack1, {hash:{}});
buffer += escapeExpression(stack1) + "</span> \r\n";
stack1 = depth0.name;
stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.noop,fn:self.program(1, program1, data)});
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "\r\n<span class='m";
foundHelper = helpers.kindName;
if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
else { stack1 = depth0.kindName; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
buffer += escapeExpression(stack1) + "'>";
stack1 = depth0.allowFormating;
stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.program(5, program5, data),fn:self.program(3, program3, data)});
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "</span><br/>";
return buffer;});
})();

View File

@ -0,0 +1 @@
Deny from all

View File

@ -0,0 +1,3 @@
<span>{{formatTime created}}</span>
{{#if name}}<span class='n{{kindName}}'>{{name}}</span>: {{/if}}
<span class='m{{kindName}}'>{{#if allowFormating}}{{apply message "urlReplace, nl2br, allowTags"}}{{else}}{{apply message "urlReplace, nl2br"}}{{/if}}</span><br/>

View File

@ -7,6 +7,9 @@
${page:additional_css}
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/common.js"></script>
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/LAB.js"></script>
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/handlebars.js"></script>
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/handlebars_helpers.js"></script>
<script type="text/javascript" language="javascript" src="${tplroot}/js/compiled/message.tpl.js"></script>
${page:additional_js}
<script type="text/javascript" language="javascript"><!--
var chatParams = {

View File

@ -0,0 +1,55 @@
(function() {
var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
templates['message'] = template(function (Handlebars,depth0,helpers,partials,data) {
helpers = helpers || Handlebars.helpers;
var buffer = "", stack1, foundHelper, functionType="function", escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing, self=this;
function program1(depth0,data) {
var buffer = "", stack1, foundHelper;
buffer += "<span class='n";
foundHelper = helpers.kindName;
if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
else { stack1 = depth0.kindName; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
buffer += escapeExpression(stack1) + "'>";
foundHelper = helpers.name;
if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
else { stack1 = depth0.name; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
buffer += escapeExpression(stack1) + "</span>: ";
return buffer;}
function program3(depth0,data) {
var stack1, foundHelper;
stack1 = depth0.message;
foundHelper = helpers.apply;
stack1 = foundHelper ? foundHelper.call(depth0, stack1, "urlReplace, nl2br, allowTags", {hash:{}}) : helperMissing.call(depth0, "apply", stack1, "urlReplace, nl2br, allowTags", {hash:{}});
return escapeExpression(stack1);}
function program5(depth0,data) {
var stack1, foundHelper;
stack1 = depth0.message;
foundHelper = helpers.apply;
stack1 = foundHelper ? foundHelper.call(depth0, stack1, "urlReplace, nl2br", {hash:{}}) : helperMissing.call(depth0, "apply", stack1, "urlReplace, nl2br", {hash:{}});
return escapeExpression(stack1);}
buffer += "<span>";
stack1 = depth0.created;
foundHelper = helpers.formatTime;
stack1 = foundHelper ? foundHelper.call(depth0, stack1, {hash:{}}) : helperMissing.call(depth0, "formatTime", stack1, {hash:{}});
buffer += escapeExpression(stack1) + "</span> \r\n";
stack1 = depth0.name;
stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.noop,fn:self.program(1, program1, data)});
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "\r\n<span class='m";
foundHelper = helpers.kindName;
if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
else { stack1 = depth0.kindName; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
buffer += escapeExpression(stack1) + "'>";
stack1 = depth0.allowFormating;
stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.program(5, program5, data),fn:self.program(3, program3, data)});
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "</span><br/>";
return buffer;});
})();

View File

@ -0,0 +1 @@
Deny from all

View File

@ -0,0 +1,3 @@
<span>{{formatTime created}}</span>
{{#if name}}<span class='n{{kindName}}'>{{name}}</span>: {{/if}}
<span class='m{{kindName}}'>{{#if allowFormating}}{{apply message "urlReplace, nl2br, allowTags"}}{{else}}{{apply message "urlReplace, nl2br"}}{{/if}}</span><br/>

View File

@ -7,6 +7,9 @@
${page:additional_css}
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/common.js"></script>
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/LAB.js"></script>
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/handlebars.js"></script>
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/handlebars_helpers.js"></script>
<script type="text/javascript" language="javascript" src="${tplroot}/js/compiled/message.tpl.js"></script>
${page:additional_js}
<script type="text/javascript" language="javascript"><!--
var chatParams = {

View File

@ -0,0 +1,55 @@
(function() {
var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
templates['message'] = template(function (Handlebars,depth0,helpers,partials,data) {
helpers = helpers || Handlebars.helpers;
var buffer = "", stack1, foundHelper, functionType="function", escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing, self=this;
function program1(depth0,data) {
var buffer = "", stack1, foundHelper;
buffer += "<span class='n";
foundHelper = helpers.kindName;
if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
else { stack1 = depth0.kindName; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
buffer += escapeExpression(stack1) + "'>";
foundHelper = helpers.name;
if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
else { stack1 = depth0.name; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
buffer += escapeExpression(stack1) + "</span>: ";
return buffer;}
function program3(depth0,data) {
var stack1, foundHelper;
stack1 = depth0.message;
foundHelper = helpers.apply;
stack1 = foundHelper ? foundHelper.call(depth0, stack1, "urlReplace, nl2br, allowTags", {hash:{}}) : helperMissing.call(depth0, "apply", stack1, "urlReplace, nl2br, allowTags", {hash:{}});
return escapeExpression(stack1);}
function program5(depth0,data) {
var stack1, foundHelper;
stack1 = depth0.message;
foundHelper = helpers.apply;
stack1 = foundHelper ? foundHelper.call(depth0, stack1, "urlReplace, nl2br", {hash:{}}) : helperMissing.call(depth0, "apply", stack1, "urlReplace, nl2br", {hash:{}});
return escapeExpression(stack1);}
buffer += "<span>";
stack1 = depth0.created;
foundHelper = helpers.formatTime;
stack1 = foundHelper ? foundHelper.call(depth0, stack1, {hash:{}}) : helperMissing.call(depth0, "formatTime", stack1, {hash:{}});
buffer += escapeExpression(stack1) + "</span> \r\n";
stack1 = depth0.name;
stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.noop,fn:self.program(1, program1, data)});
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "\r\n<span class='m";
foundHelper = helpers.kindName;
if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
else { stack1 = depth0.kindName; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
buffer += escapeExpression(stack1) + "'>";
stack1 = depth0.allowFormating;
stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.program(5, program5, data),fn:self.program(3, program3, data)});
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "</span><br/>";
return buffer;});
})();

View File

@ -0,0 +1 @@
Deny from all

View File

@ -0,0 +1,3 @@
<span>{{formatTime created}}</span>
{{#if name}}<span class='n{{kindName}}'>{{name}}</span>: {{/if}}
<span class='m{{kindName}}'>{{#if allowFormating}}{{apply message "urlReplace, nl2br, allowTags"}}{{else}}{{apply message "urlReplace, nl2br"}}{{/if}}</span><br/>

View File

@ -8,6 +8,9 @@
${page:additional_css}
<script type="text/javascript" src="${webimroot}/js/${jsver}/common.js"></script>
<script type="text/javascript" src="${webimroot}/js/${jsver}/LAB.js"></script>
<script type="text/javascript" src="${webimroot}/js/${jsver}/handlebars.js"></script>
<script type="text/javascript" src="${webimroot}/js/${jsver}/handlebars_helpers.js"></script>
<script type="text/javascript" src="${tplroot}/js/compiled/message.tpl.js"></script>
${page:additional_js}
<script type="text/javascript">
<!--

View File

@ -0,0 +1,55 @@
(function() {
var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
templates['message'] = template(function (Handlebars,depth0,helpers,partials,data) {
helpers = helpers || Handlebars.helpers;
var buffer = "", stack1, foundHelper, functionType="function", escapeExpression=this.escapeExpression, helperMissing=helpers.helperMissing, self=this;
function program1(depth0,data) {
var buffer = "", stack1, foundHelper;
buffer += "<span class='n";
foundHelper = helpers.kindName;
if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
else { stack1 = depth0.kindName; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
buffer += escapeExpression(stack1) + "'>";
foundHelper = helpers.name;
if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
else { stack1 = depth0.name; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
buffer += escapeExpression(stack1) + "</span>: ";
return buffer;}
function program3(depth0,data) {
var stack1, foundHelper;
stack1 = depth0.message;
foundHelper = helpers.apply;
stack1 = foundHelper ? foundHelper.call(depth0, stack1, "urlReplace, nl2br, allowTags", {hash:{}}) : helperMissing.call(depth0, "apply", stack1, "urlReplace, nl2br, allowTags", {hash:{}});
return escapeExpression(stack1);}
function program5(depth0,data) {
var stack1, foundHelper;
stack1 = depth0.message;
foundHelper = helpers.apply;
stack1 = foundHelper ? foundHelper.call(depth0, stack1, "urlReplace, nl2br", {hash:{}}) : helperMissing.call(depth0, "apply", stack1, "urlReplace, nl2br", {hash:{}});
return escapeExpression(stack1);}
buffer += "<span>";
stack1 = depth0.created;
foundHelper = helpers.formatTime;
stack1 = foundHelper ? foundHelper.call(depth0, stack1, {hash:{}}) : helperMissing.call(depth0, "formatTime", stack1, {hash:{}});
buffer += escapeExpression(stack1) + "</span> \r\n";
stack1 = depth0.name;
stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.noop,fn:self.program(1, program1, data)});
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "\r\n<span class='m";
foundHelper = helpers.kindName;
if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); }
else { stack1 = depth0.kindName; stack1 = typeof stack1 === functionType ? stack1() : stack1; }
buffer += escapeExpression(stack1) + "'>";
stack1 = depth0.allowFormating;
stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.program(5, program5, data),fn:self.program(3, program3, data)});
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "</span><br/>";
return buffer;});
})();

View File

@ -0,0 +1 @@
Deny from all

View File

@ -0,0 +1,3 @@
<span>{{formatTime created}}</span>
{{#if name}}<span class='n{{kindName}}'>{{name}}</span>: {{/if}}
<span class='m{{kindName}}'>{{#if allowFormating}}{{apply message "urlReplace, nl2br, allowTags"}}{{else}}{{apply message "urlReplace, nl2br"}}{{/if}}</span><br/>

View File

@ -7,6 +7,9 @@
${page:additional_css}
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/common.js"></script>
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/LAB.js"></script>
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/handlebars.js"></script>
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/handlebars_helpers.js"></script>
<script type="text/javascript" language="javascript" src="${tplroot}/js/compiled/message.tpl.js"></script>
${page:additional_js}
<script type="text/javascript" language="javascript"><!--
var chatParams = {

View File

@ -17,6 +17,27 @@
$page['title'] = getlocal("thread.chat_log");
function tpl_header() { global $page, $webimroot, $jsver; ?>
<script type="text/javascript" src="<?php echo($webimroot); ?>/js/<?php echo($jsver); ?>/common.js"></script>
<script type="text/javascript" src="<?php echo($webimroot); ?>/js/<?php echo($jsver); ?>/handlebars.js"></script>
<script type="text/javascript" src="<?php echo($webimroot); ?>/js/<?php echo($jsver); ?>/handlebars_helpers.js"></script>
<script type="text/javascript" src="<?php echo($webimroot); ?>/js/<?php echo($jsver); ?>/messageview.js"></script>
<script type="text/javascript" src="<?php echo($webimroot); ?>/js/templates/compiled/message.tpl.js"></script>
<script type="text/javascript"><!--
EventHelper.register(window, 'onload', function() {
var threadMessages = <?php echo($page['threadMessages']); ?>;
var messageEl = document.getElementById('message');
var messageView = new MessageView();
for (var index in threadMessages) {
if (! threadMessages.hasOwnProperty(index)) {
continue;
}
messageEl.innerHTML += messageView.themeMessage(threadMessages[index]);
}
});
// --></script>
<?php }
function tpl_content() { global $page, $webimroot, $errors;
$chatthreadinfo = $page['thread_info'];
$chatthread = $page['thread_info']['thread'];
@ -83,7 +104,7 @@ $chatthread = $page['thread_info']['thread'];
<br clear="all"/>
</div>
<div class="message">
<div class="message" id="message">
<?php
foreach( $page['threadMessages'] as $message ) {
echo $message;