Skip to content

Instantly share code, notes, and snippets.

@Maxdamantus
Last active June 1, 2018 09:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Maxdamantus/745b8ffb36adef889e5aa94b0f6ac49b to your computer and use it in GitHub Desktop.
Save Maxdamantus/745b8ffb36adef889e5aa94b0f6ac49b to your computer and use it in GitHub Desktop.
body {
margin: 0px;
font: DejaVu Sans !important;
}
div.MessageRight {
display: inline;
}
span.MessageTimeStamp, span.MessageNameField {
font-family: monospace;
}
span.MessageNameField {
color: #ff0000;
}
span.MessageTimeStamp, span.MessageText, span.MessageNameField {
font-size: 12px;
}
div.Message.Self {
background-color: #000000;
color: #ffffff;
}
div.Message.Other {
background-color: #333333;
color: #ffffff;
}
a {
color: #aaaaff;
}
/**
* Style rules for the MessageBuffer
*/
/**
* the body defaults
*/
body {
word-wrap: break-word;
padding: 0px 16px;
}
div.Bubble {
display: table-cell;
vertical-align: middle;
padding: 0px;
line-height: 130%;
}
div.InnerBubble {
display: block;
}
div.Message {
margin-top: 8px;
margin-left: 0px;
margin-right: 0px;
display: table;
width: 100%;
}
div.Message:first-child {
margin-top: 0px;
}
/**
* The Message notice message format
*/
div.MessageNormal {
text-align: left;
vertical-align: middle;
}
div.MessageNotice {
}
div.MessageActionSelf {
}
div.MessageActionOther {
}
div.MessageAutoReply {
}
/**
* Avatars
*/
img.MessageAvatar {
width: 64px;
height: 64px;
padding: 1px;
vertical-align: top;
outline-style: solid;
outline-width: 3px;
outline-offset: -1px;
-moz-outline-radius: 6px;
}
div.MessageAvatar {
vertical-align: top;
display: table-cell;
padding-left: 8px;
padding-right: 8px;
padding-top: 1px;
}
div.MessageAvatarBorder {
z-index: 1;
width: 64px;
height: 64px;
position: absolute;
display: inline-block;
-moz-border-radius: 6px;
border-width: 1px;
border-style: solid;
}
img.MessagePresence {
width: 16px;
height: 16px;
vertical-align: middle;
}
/**
* the Name field
*/
.MessageNameField {
word-wrap: break-word;
}
/**
* the Text field
*/
.MessageText {
word-wrap: break-word;
min-height: 80px;
}
/**
* the NameSeparator field
*/
.MessageNameSeparator {
}
span.MessageRight {
display: table-cell;
margin-left: 8px;
}
/**
* the TimeStamp default rules
*/
span.MessageTimeStamp {
white-space: nowrap;
}
.MessagingWidgetsSmiley {
height: 24px;
width: 24px;
}
/**
* Style rules for the MessageBuffer
*/
/**
* the body defaults
*/
body {
word-wrap: break-word;
padding: 0px 16px;
}
div.Bubble {
width: 672px;
display: table-cell;
vertical-align: middle;
padding: 0px;
line-height: 130%;
}
div.InnerBubble {
width: 672px;
display: block;
}
div.Message {
margin-top: 8px;
margin-left: 0px;
margin-right: 0px;
}
div.Message:first-child {
margin-top: 0px;
}
/**
* The Message notice message format
*/
div.MessageNormal {
text-align: left;
vertical-align: middle;
}
div.MessageNotice {
}
div.MessageActionSelf {
}
div.MessageActionOther {
}
div.MessageAutoReply {
}
/**
* Avatars
*/
img.MessageAvatar {
width: 64px;
height: 64px;
padding: 1px;
vertical-align: top;
outline-style: solid;
outline-width: 3px;
outline-offset: -1px;
-moz-outline-radius: 6px;
}
div.MessageAvatar {
vertical-align: top;
display: table-cell;
padding-left: 8px;
padding-right: 8px;
padding-top: 1px;
}
div.MessageAvatarBorder {
z-index: 1;
width: 64px;
height: 64px;
position: absolute;
display: inline-block;
-moz-border-radius: 6px;
border-width: 1px;
border-style: solid;
}
img.MessagePresence {
width: 16px;
height: 16px;
vertical-align: middle;
}
/**
* the Name field
*/
.MessageNameField {
word-wrap: break-word;
}
/**
* the Text field
*/
.MessageText {
word-wrap: break-word;
min-height: 80px;
}
/**
* the NameSeparator field
*/
.MessageNameSeparator {
}
span.MessageRight {
display: inline-block;
margin-left: 8px;
float: right;
}
/**
* the TimeStamp default rules
*/
span.MessageTimeStamp {
white-space: nowrap;
}
.MessagingWidgetsSmiley {
height: 24px;
width: 24px;
}
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- messaging-widgets -->
<html>
<head>
<link rel="stylesheet" type="text/css" href="MessagingWidgetsChatConversation.css"></link>
<link rel="stylesheet" type="text/css" href="/etc/hildon/theme/css/colors.css" id="ThemeCSSLink"></link>
<link rel="stylesheet" type="text/css" href="" id="ThemeCSSLinkUser"></link>
<script type="text/javascript" src="MessagingWidgetsDebug.js"></script>
<script type="text/javascript" src="MessagingWidgetsChatConversation.js"></script>
</head>
<!-- Preserve the tag IDs. Everything else can be changed and rearranged -->
<body class="DefaultBackgroundColor DefaultTextColor SystemFont " onload="MessagingWidgetsChatConversation_init()">
<div id="MessageContainerSelf" class="Message MessageNormal Self" style="display:none">
<div class="MessageAvatar MessageAvatarSelf"><div id="AvatarImgBorderSelf" class="MessageAvatarBorder Self MessagingAvatarBorderColor"></div>
<img id="AvatarImgSelf" src="" class="MessageAvatar MessagingAvatarBorderMaskColor " />
</div>
<div id="MessageAvatarAlternativeSelf" class="MessageAvatar MessageAvatarAlternative" style="display:none;"></div>
<div id="MessageSelf" class="Bubble BubbleNormal"><div class="InnerBubble">
<img id="MessagePresenceSelf" src="" width="16" height="16" class="MessagePresence" />
<span id="MessageSenderNameSelf" class="MessageNameField EmpSystemFont AccentColor2"></span>
<span id="MessageTextSelf" class="MessageText Self"></span>
<span class="MessageRight">
<span id="MessageTimeStampSelf" class="MessageTimeStamp SecondaryTextColor Self SmallSystemFont" style="display: inline-block;"></span>
</span>
<div class="vertical left"></div><div class="vertical right"></div><div class="horizontal top"></div><div class="horizontal bottom"></div>
<div class="corner top-left"></div><div class="corner top-right"></div><div class="corner bottom-left"></div><div class="corner bottom-right"></div>
<div class="self-point"></div>
</div>
</div>
</div>
<div id="MessageContainerOther" class="Message MessageNormal Other" style="display:none">
<div class="MessageAvatar MessageAvatarOther"><div id="AvatarImgBorderOther" class="MessageAvatarBorder Other MessagingAvatarBorderColor"></div>
<img id="AvatarImgOther" src="" class="MessageAvatar MessagingAvatarBorderMaskColor " />
</div>
<div id="MessageAvatarAlternativeOther" class="MessageAvatar MessageAvatarAlternative" style="display:none;"></div>
<div id="MessageOther" class="Bubble BubbleNormal"><div class="InnerBubble">
<img id="MessagePresenceOther" src="" width="16" height="16" class="MessagePresence" />
<span id="MessageSenderNameOther" class="MessageNameField EmpSystemFont AccentColor1"></span>
<span id="MessageTextOther" class="MessageText Other"></span>
<span class="MessageRight">
<span id="MessageTimeStampOther" class="MessageTimeStamp SecondaryTextColor Other SmallSystemFont" style="display: inline-block;"></span>
</span>
<div class="vertical left"></div><div class="vertical right"></div><div class="horizontal top"></div><div class="horizontal bottom"></div>
<div class="corner top-left"></div><div class="corner top-right"></div><div class="corner bottom-left"></div><div class="corner bottom-right"></div>
<div class="other-point"></div>
</div>
</div>
</div>
<div id="MessageContainerNotice" class="Message MessageNotice EmpSystemFont SecondaryTextColor" style="display:none">
<div id="MessageNotice" class="Bubble BubbleNotice"><div class="InnerBubbleNotice">
<span id="MessageTextNotice" class="MessageText "></span>
</div></div>
</div>
<div id="MessageContainerAction" class="Message MessageAction Action EmpSystemFont" style="display:none">
<div class="MessageAvatar MessageAvatarAction"><div id="AvatarImgBorderAction" class="MessageAvatarBorder Action MessagingAvatarBorderColor"></div>
<img id="AvatarImgAction" src="" class="MessageAvatar MessagingAvatarBorderMaskColor " />
</div>
<div id="MessageAvatarAlternativeAction" class="MessageAvatar MessageAvatarAlternative" style="display:none;"></div>
<div id="MessageAction" class="Bubble BubbleAction"><div class="InnerBubble InnerBubble">
<img id="MessagePresenceAction" src="" width="16" height="16" class="MessagePresence" />
<span id="MessageSenderNameAction" class="MessageNameField EmpSystemFont Action"></span>
<span id="MessageTextAction" class="MessageText Action"></span>
<span class="MessageRight">
<span id="MessageTimeStampAction" class="MessageTimeStamp SecondaryTextColor Action SmallSystemFont" style="display: inline-block;"></span>
</span>
</div></div>
</div>
<div id="MessageContainerAutoReply" class="Message MessageAutoReply Self" style="display:none;">
<div class="MessageAvatar"><div id="AvatarImgBorderAutoReply" class="MessageAvatarBorder Self MessagingAvatarBorderColor"></div>
<img id="AvatarImgAutoReply" src="" class="MessageAvatar MessagingAvatarBorderMaskColor " />
</div>
<div id="MessageAutoReply" class="Bubble"><div class="InnerBubble InnerBubbleAutoReply">
<span id="MessageSenderNameAutoReply" class="MessageNameField EmpSystemFont AccentColor1"></span>
<span id="MessageTextAutoReply" class="MessageText Self"></span>
<span class="MessageRight">
<span id="MessageTimeStampAutoReply" class="MessageTimeStamp SecondaryTextColor Self SmallSystemFont" style="display: inline-block;"></span>
</span>
</div></div>
</div>
</body>
</html>
/**
* @file MessagingWidgetsChatConversation.js
*
* Javascript for messaging rendering widget's ring buffer.
*/
/*
* This file is part of rtcom messaging ui
*
* Copyright (C) 2009 Nokia Corporation. All rights reserved.
*
* Contact: Naba Kumar <naba.kumar@nokia.com>
*
* This software, including documentation, is protected by copyright
* controlled by Nokia Corporation. All rights are reserved.
* Copying, including reproducing, storing, adapting or translating,
* any or all of this material requires the prior written consent of
* Nokia Corporation. This material also contains confidential
* information which may not be disclosed to others without the prior
* written consent of Nokia.
*/
/**
* Globals:
*
* @myShowTimes: Display method for time stamps, set to 'inline' to show
* and 'none' to hide
*
**/
var HISTORY_BATCH_SIZE = 30;
var HISTORY_PAGE_SIZE = 15;
var HISTORY_SCREENFULL_SIZE = 6;
var HISTORY_FETCHING_DONE = -1;
var HISTORY_FETCHING_NOREQUEST = 0;
/* if HISTORY_FETCHING_NOREQUEST, no batch has been requested.
* if HISTORY_FETCHING_DONE, history fetching done; no more request to give.
* if > 0, request in progress and the amount requested.
*/
var myBatchRequested = 0;
var myShowTimes = "inline";
var myMaxMessages = -1;
var markupTemplateSelf;
var markupTemplateOther;
var markupTemplateNotice;
var markupTemplateAction;
var markupTemplateAutoReply;
var fakeid = 1;
var messagesBuffer = new Array();
var pastPresenceAnchor = new Array();
var firstFlush = true;
var flushTimeout = 0;
var storedWindowHeight = 340;
var storedScreenHeight = 0;
var storedBottomElement;
/**
* MessagingWidgetsChatConversation_init:
*
* Called when the page has actually been loaded.
* Acts as a "constructor", could be used for creating the template item and
* getting the element where we will add the children in the page.
*
* However, creating such template items doesn't seem so simple, we would
* need several of them in order to be able to keep it really usable.
**/
function MessagingWidgetsChatConversation_init ()
{
/* Setting onscroll handler to window */
window.onscroll = MessagingWidgetsRenderer_onScroll;
/* Setting onresize handler to window */
window.onresize = MessagingWidgetsRenderer_onResize;
storedScreenHeight = screen.height;
storedWindowHeight = storedScreenHeight - 140;
if (!markupTemplateSelf)
{
markupTemplateSelf = document.getElementById("MessageContainerSelf");
markupTemplateSelf.parentNode.removeChild(markupTemplateSelf);
markupTemplateSelf.removeAttribute('id');
markupTemplateOther = document.getElementById("MessageContainerOther");
markupTemplateOther.parentNode.removeChild(markupTemplateOther);
markupTemplateOther.removeAttribute('id');
markupTemplateNotice = document.getElementById("MessageContainerNotice");
markupTemplateNotice.parentNode.removeChild(markupTemplateNotice);
markupTemplateNotice.removeAttribute('id');
markupTemplateAction = document.getElementById(
"MessageContainerAction");
markupTemplateAction.parentNode.removeChild(
markupTemplateAction);
markupTemplateAction.removeAttribute('id');
markupTemplateAutoReply = document.getElementById("MessageContainerAutoReply");
markupTemplateAutoReply.parentNode.removeChild(markupTemplateAutoReply);
markupTemplateAutoReply.removeAttribute('id');
}
}
function MessagingWidgetsRenderer_avatarBorderClicked (event)
{
alert(event.currentTarget.id);
event.returnValue = true;
event.cancelBubble = false;
}
/*
* Fixes presence...
*/
function
MessagingWidgetsRenderer_fixPresence (
self, presence_img, presence, contact_info_str, add_to_top)
{
var presenceID;
if (!presence_img) return;
presenceID = "PresenceImg" + contact_info_str;
if (!self) {
presence_img.id = presenceID;
if (presence != null && presence != "") {
presence_img.src = presence;
}
/* Find current presence anchor in document */
var prevPresence = document.getElementById (presenceID);
if (add_to_top) {
/* If we are adding a history, check if presence anchor is
* already present in document (presumably added at bottom
* from pending messages) or in pastPresenceAnchor which
* remebers if we already created the anchor (it should
* not be re-created if already created when populating
* history).
*/
if (prevPresence ||
pastPresenceAnchor[contact_info_str] == true) {
/*
* Presence is already anchored; remove it from this item.
*/
presence_img.parentNode.removeChild (presence_img);
} else{
/*
* There is no anchor found, either in document or in
* previously anchored, so leave presence node intact
* in this item and record that anchor is already set.
*/
pastPresenceAnchor[contact_info_str] = true;
}
} else {
/* If we found a previous presence icon, we remove that.
* this one replaces the anchor
*/
if (prevPresence) {
prevPresence.parentNode.removeChild (prevPresence);
}
}
} else if (presence_img) {
presence_img.parentNode.removeChild (presence_img);
}
}
/**
* MessagingWidgetsRenderer_messagePress:
* @event: The message.
*
* Handles onMousePress event and emits the event upwards to C-code via alert()
**/
function MessagingWidgetsRenderer_messagePress (event)
{
var idstr;
idstr = "file://pre-id:"+event.currentTarget.id;
alert(idstr);
event.returnValue = true;
/* Canceling bubble so body onmousedown isn't called */
event.cancelBubble = true;
}
/**
* MessagingWidgetsRenderer_messageNode:
* @item: The message.
* @add_to_top: Add the new message to the top of the list
*
* Creates a message node
**/
function
MessagingWidgetsRenderer_messageNode (item, add_to_top)
{
/* Top level items */
var new_message;
var new_message_template;
/* Avatar data */
var avatar_img;
var avatar_img_border;
/* The graphics */
var bubble_cell;
/* Presence icon and name area */
var presence_img;
var name_tag;
/* Message text content */
var message_txt;
/* Time stamps and potential icons */
var time_tag;
var delivery_time_tag;
var business_img;
var type_name;
var count;
if (!markupTemplateSelf) {
MessagingWidgetsChatConversation_init ();
}
if (item.type == 2) {
new_message_template = markupTemplateNotice;
type_name = "Notice";
} else if (item.type == 1) {
new_message_template = markupTemplateAction;
type_name = "Action";
} else if (item.type == 3) {
new_message_template = markupTemplateAutoReply;
type_name = "AutoReply";
} else {
if (item.self) {
new_message_template = markupTemplateSelf;
type_name = "Self";
} else {
new_message_template = markupTemplateOther;
type_name = "Other";
}
}
new_message = new_message_template.cloneNode(true);
if (item.id_str == null || item.id_str == "") {
item.id_str = "GeneratedId_" + fakeid++;
}
new_message.id = "Message" + item.id_str;
new_message.onmousedown = MessagingWidgetsRenderer_messagePress;
/* Retrieve the elements to update */
var node_tags = new_message.getElementsByTagName('*');
for (var i = 0; i < node_tags.length; i++) {
if (node_tags[i].hasAttribute('id')) {
var id = node_tags[i].getAttribute('id');
if (id == ("AvatarImg" + type_name))
avatar_img = node_tags[i];
if (id == ("AvatarImgBorder" + type_name))
avatar_img_border = node_tags[i];
if (id == ("Message" + type_name))
bubble_cell = node_tags[i];
if (id == ("MessagePresence" + type_name))
presence_img = node_tags[i];
if (id == ("MessageSenderName" + type_name))
name_tag = node_tags[i];
if (id == ("MessageText" + type_name))
message_txt = node_tags[i];
if (id == ("MessageTimeStamp" + type_name))
time_tag = node_tags[i];
}
}
/* Setting sender's name color */
if (item.type == 1) {
if (item.self) {
name_tag.className += " AccentColor2";
} else {
name_tag.className += " AccentColor1";
}
}
bubble_cell.id = item.id_str;
message_txt.id = "MessageText" + item.id_str;
if (avatar_img) avatar_img.id = "avatar:" + item.contact_info_str;
if (avatar_img_border) avatar_img_border.id = "avatar:" + item.contact_info_str;
if (name_tag) name_tag.id = "MessageSenderName" + item.id_str;
if (time_tag) time_tag.id = "MessageTimeStamp" + item.id_str;
/* Creation of an avatar image */
if (avatar_img) {
avatar_img.src = item.avatar;
}
if (avatar_img_border) {
avatar_img_border.onclick =
MessagingWidgetsRenderer_avatarBorderClicked;
}
if (item.name_str != "" && name_tag) {
name_tag.innerHTML = item.name_str;
}
message_txt.innerHTML = item.message_str.replace(/\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
message_txt.setAttribute("dir", item.text_dir);
if (time_tag) {
time_tag.style.display = myShowTimes;
time_tag.innerHTML = item.time_str;
}
/* Show the new message */
new_message.style.display = "block";
/* FIXME: Move it somewhere appropriate */
MessagingWidgetsRenderer_fixPresence(item.self, presence_img, item.presence,
item.contact_info_str, add_to_top);
return new_message;
}
/**
* MessagingWidgetsRenderer_messageObject:
* @type: Type of the message (normal/action/notice/autoreply)
* @time_str: The time string to show in the screen
* @delivery_str: The delivery time string to possibly show in the screen
* @name_str: The name string to show in the screen
* @message_str: The actual message to show
* @self: TRUE if message is from self
* @id_str: The ID of the message for access
* @avatar: path(/url?) to avatar image
* @presence: presence icon of sender
* @business_icon: path to business card icon
* @status_icon: path to message status icon (pending/failed)
* @contact_info_str: Additional contact information
* @text_dir: Text direction ("ltr" or "rtl")
*
* Creates a message object.
**/
function
MessagingWidgetsRenderer_messageObject (
type, time_str, delivery_str, name_str, message_str, self, id_str,
avatar, presence, business_icon, status_icon, contact_info_str, text_dir)
{
this.type = type;
this.time_str = time_str;
this.delivery_str = delivery_str;
this.name_str = name_str;
this.message_str = message_str;
this.self = self;
this.id_str = id_str;
this.avatar = avatar;
this.presence = presence;
this.business_icon = business_icon;
this.status_icon = status_icon;
this.contact_info_str = contact_info_str;
this.text_dir = text_dir;
}
/*
* Flushes the given amount of messages from the buffer to renderer
*/
function
MessagingWidgetsRenderer_flushBuffer (amount)
{
if (messagesBuffer.length > 0) {
if (amount < 0)
amount = messagesBuffer.length;
var fragment = document.createDocumentFragment();
for (var i = 0; i < amount; i++) {
if (messagesBuffer.length <= 0)
break;
var item = messagesBuffer.shift();
new_message =
MessagingWidgetsRenderer_messageNode (item, true);
if (fragment.childNodes.length > 0)
fragment.insertBefore(new_message, fragment.firstChild);
else
fragment.appendChild(new_message);
}
/* Restore scroll position */
var savedScrollPos =
document.body.scrollHeight - window.pageYOffset;
document.body.insertBefore(fragment, document.body.firstChild);
window.sizeToContent();
window.scrollTo(0, (document.body.scrollHeight - savedScrollPos));
}
}
/* Scroll event handler to potentially add more past history */
function
MessagingWidgetsRenderer_onScroll (event)
{
/* Buffer flushing if there isn't already one running. */
if (window.pageYOffset < 100 && messagesBuffer.length > 0) {
/* Add a page of messages (about 4 screen-full) to renderer */
MessagingWidgetsRenderer_flushBuffer(HISTORY_PAGE_SIZE);
}
/* If we run out of messages in buffer and history hasn't finished,
* request for more
*/
if (messagesBuffer.length == 0 &&
myBatchRequested == HISTORY_FETCHING_NOREQUEST) {
myBatchRequested = HISTORY_BATCH_SIZE;
alert("history-request:" + HISTORY_BATCH_SIZE);
}
obj=document.elementFromPoint(120, window.innerHeight-16);
if(obj.id != "")
storedBottomElement = obj;
}
/* When conversation view editor expands/shrinks, scroll accordingly to */
/* keep the the bottom position of the screen fixed. */
function
MessagingWidgetsRenderer_onResize (event)
{
if( storedScreenHeight != screen.height)
{
storedBottomElement.scrollIntoView(false);
storedScreenHeight = screen.height;
storedWindowHeight = window.innerHeight;
}
if (Math.abs(storedWindowHeight - window.innerHeight) != 0) {
window.scrollBy(0, storedWindowHeight - window.innerHeight);
storedWindowHeight = window.innerHeight;
}
}
/**
* MessagingWidgetsRenderer_addMessage:
* @type: Type of the message (normal/action/notice/autoreply)
* @time_str: The time string to show in the screen
* @delivery_str: The delivery time string to possibly show in the screen
* @name_str: The name string to show in the screen
* @message_str: The actual message to show
* @self: TRUE if message is from self
* @id_str: The ID of the message for access
* @avatar: path(/url?) to avatar image
* @presence: presence icon of sender
* @business_icon: path to business card icon
* @status_icon: path to message status icon (pending/failed)
* @contact_info_str: Additional contact information
* @add_to_top: Add the new message to the top of the list
* @text_dir: Text direction ("ltr" or "rtl")
*
* Queues messages to buffer and triggers flush schedule. Also forces
* an immediate flush if there are 5 messages already in buffer for
* the first time. It's a screenful of messages shown to the user in
* first opportunity.
**/
function
MessagingWidgetsRenderer_addMessage (
type, time_str, delivery_str, name_str, message_str, self, id_str,
avatar, presence, business_icon, status_icon, contact_info_str, add_to_top,
text_dir)
{
var item =
new MessagingWidgetsRenderer_messageObject (type, time_str,
delivery_str,
name_str, message_str,
self, id_str, avatar,
presence, business_icon,
status_icon,
contact_info_str,
text_dir);
if (add_to_top) {
/* Queue the top (history) message in buffer. */
messagesBuffer[messagesBuffer.length] = item;
/* Force flush if there's already screenful of messages to show for
* the first time.
*/
if (firstFlush == true &&
messagesBuffer.length >= HISTORY_SCREENFULL_SIZE) {
firstFlush = false;
MessagingWidgetsRenderer_flushBuffer(HISTORY_SCREENFULL_SIZE);
}
} else {
/* If the message is bottom, add it directly without queuing. */
var new_message =
MessagingWidgetsRenderer_messageNode (item, false);
document.body.appendChild (new_message);
window.sizeToContent();
/* scrolling to new message, if the view is close to bottom, or */
/* sent by self. If not, we don't scroll */
if (document.body.scrollHeight - window.pageYOffset < (screen.height-140)*2 || self) {
new_message.scrollIntoView (false);
}
}
}
/**
* MessagingWidgetsRenderer_batchAdded:
* @messages_fetched: Number of messages fetched from log
*
* History batch has been added to renderer
**/
function MessagingWidgetsRenderer_batchAdded (messages_fetched)
{
/* Force flush if there hasn't been anything shown yet.
* This happens because the first batch was smaller than
* HISTORY_SCREENFULL_SIZE.
*/
if (firstFlush == true && messagesBuffer.length >= 0) {
firstFlush = false;
MessagingWidgetsRenderer_flushBuffer(-1);
}
/* If there was no request made, then it's the first batch pushed.
* The subsequent batch is requested after a delay of 1s to allow
* first screenfull to be rendered properly.
*/
if (myBatchRequested == HISTORY_FETCHING_NOREQUEST) {
if (flushTimeout != 0)
clearTimeout(flushTimeout);
flushTimeout = setTimeout("MessagingWidgetsRenderer_onScroll();",
1000);
} else if (myBatchRequested > 0) {
/* If there was a request, check if we got everything.
* If received messages is the amount requested, we could
* continue fetching more, otherwise there is no more history
* to fetch.
*/
if (messages_fetched < myBatchRequested) {
myBatchRequested = HISTORY_FETCHING_DONE; /* No more history */
} else {
myBatchRequested = HISTORY_FETCHING_NOREQUEST; /* Batch delivered */
}
/* Check if anything needs to be rendered at this scroll position */
MessagingWidgetsRenderer_onScroll();
}
}
/**
* MessagingWidgetsRenderer_deleteMessage:
* @id_str: The ID of the message to delete
*
* Removes a message from the message area
**/
function MessagingWidgetsRenderer_deleteMessage (id_str)
{
var txt;
var node = null;
MessagingWidgetsDebug_print (
"MessagingWidgetsRenderer_deleteMessage("+id_str+") called.");
txt = "Message"+id_str;
node = document.getElementById(txt);
if (node == null) {
MessagingWidgetsDebug_print ("No messages with id: " + id_str);
return;
}
try {
document.body.removeChild (node);
window.scrollBy (0,0);
} catch (e) {
MessagingWidgetsDebug_print (
"Message " + index + " removal failed: " + e);
}
return;
}
/**
* MessagingWidgetsRenderer_showDeliveryTimes:
* @visibility: Set to 'inline' to show delivery time stamps. Set to
* 'none' not to show them.
*
* Set if delivery time stamps should be visible
**/
function MessagingWidgetsRenderer_showDeliveryTimes (visibility)
{
var times;
if (visibility != "inline" && visibility != "none") {
MessagingWidgetsDebug_print(
"MessagingWidgetsRenderer_showDeliveryTimes: Illegal parameter: "
+ visibility);
return;
}
myShowTimes = visibility;
times = document.getElementsByTagName("span");
if (times == null) {
return;
}
MessagingWidgetsDebug_print("span elements: "+times.length);
for (i = 0; i < times.length; i++) {
if (times[i].className.indexOf ("MessageDeliveryTimeStamp") != -1) {
times[i].style.display = myShowTimes;
}
}
return;
}
/**
* MessagingWidgetsRenderer_setTimes:
* @id_str: id of the message
* @time_str: message time stamp
* @delivery_str: message delivery time stamp
* @status_icon: path+name of a status icon (pending/failed)
*
* Set time stamps and status icon
**/
function MessagingWidgetsRenderer_setTimes (id_str, time_str, delivery_str,
status_icon)
{
var icon;
// Weird new browser behaviour here. Looks like if the src of the status
// icon is set to not valid icon value, the browser keeps displaying the old
// valid icon. Only when you put to the src a valid icon does it change.
// Worked around this by hiding the image altogether if the icon is set
// to "".
icon = document.getElementById("MessageStatusImg"+id_str);
if (icon != null) {
icon.src = status_icon;
if (status_icon == "") {
icon.style.display = "none";
} else {
icon.style.display = "inline";
}
}
document.getElementById("MessageTimeStamp"+id_str).innerHTML = time_str;
document.getElementById("MessageDeliveryTimeStamp"+id_str).innerHTML =
delivery_str;
return;
}
/**
* MessagingWidgetsRenderer_setPresence:
* @contact_info: The contact info for presence icon
* @presence: Presence icon path
*
* Sets the presence icon of @contact_info to @presence
**/
function MessagingWidgetsRenderer_setPresence (contact_info, presence)
{
var presenceImg = document.getElementById ("PresenceImg" + contact_info);
if (presenceImg != null) {
presenceImg.src = presence;
} else {
/* Find in buffer */
for (var i = 0; i < messagesBuffer.length; i++) {
if (messagesBuffer[i].contact_info_str == contact_info) {
messagesBuffer[i].presence = presence;
break;
}
}
}
}
/**
* MessagingWidgetsRenderer_setMaxMessages:
* @max: maximum number of messages
*
* Sets the maximum number of messages (default is 50)
**/
function MessagingWidgetsRenderer_setMaxMessages (max)
{
var count;
myMaxMessages = max;
count = document.body.childNodes.count;
if (count >= myMaxMessages) {
var i;
for (i = count - myMaxMessages + 1; i > 0; i--) {
document.body.removeChild (document.body.firstChild);
}
}
return;
}
/**
* MessagingWidgetsRenderer_setCSS:
* @file: Path of theme CSS file
*
* Sets the system theme CSS file to the current page.
*
**/
function MessagingWidgetsRenderer_setCSS (file)
{
document.getElementById("ThemeCSSLink").href = file;
return;
}
/**
* MessagingWidgetsRenderer_setTheme:
* @theme: Theme name to set
*
* Sets the user theme.
*
**/
function MessagingWidgetsRenderer_setTheme (theme)
{
if (!theme || theme == '')
document.getElementById("ThemeCSSLinkUser").href = "";
else
document.getElementById("ThemeCSSLinkUser").href = theme + "/theme.css";
}
/**
* MessagingWidgetsRenderer_addBatch:
*
* @messages: Array of messages to add
*
* Adds several messages to view
*
**/
function MessagingWidgetsRenderer_addBatch (messages)
{
var len = messages.length;
var i;
// starting from 1, because of the extra ',' at the beginning due to
// performance optimizations
for(i=1; i<len; i++) {
// Calling addMessage for each batched call. Converting strings
// representing bool/int parameters
MessagingWidgetsRenderer_addMessage(Number(messages[i][0]),
messages[i][1], messages[i][2], messages[i][3], messages[i][4],
(messages[i][5] === 'true'), messages[i][6], messages[i][7],
messages[i][8], messages[i][9], messages[i][10], messages[i][11],
(messages[i][12]) === 'true', messages[i][13]);
}
return;
}
/**
* @file MessagingWidgetsChatConversation.js
*
* Javascript for messaging rendering widget's ring buffer.
*/
/*
* This file is part of rtcom messaging ui
*
* Copyright (C) 2009 Nokia Corporation. All rights reserved.
*
* Contact: Naba Kumar <naba.kumar@nokia.com>
*
* This software, including documentation, is protected by copyright
* controlled by Nokia Corporation. All rights are reserved.
* Copying, including reproducing, storing, adapting or translating,
* any or all of this material requires the prior written consent of
* Nokia Corporation. This material also contains confidential
* information which may not be disclosed to others without the prior
* written consent of Nokia.
*/
/**
* Globals:
*
* @myShowTimes: Display method for time stamps, set to 'inline' to show
* and 'none' to hide
*
**/
var HISTORY_BATCH_SIZE = 30;
var HISTORY_PAGE_SIZE = 15;
var HISTORY_SCREENFULL_SIZE = 6;
var HISTORY_FETCHING_DONE = -1;
var HISTORY_FETCHING_NOREQUEST = 0;
/* if HISTORY_FETCHING_NOREQUEST, no batch has been requested.
* if HISTORY_FETCHING_DONE, history fetching done; no more request to give.
* if > 0, request in progress and the amount requested.
*/
var myBatchRequested = 0;
var myShowTimes = "inline";
var myMaxMessages = -1;
var markupTemplateSelf;
var markupTemplateOther;
var markupTemplateNotice;
var markupTemplateAction;
var markupTemplateAutoReply;
var fakeid = 1;
var messagesBuffer = new Array();
var pastPresenceAnchor = new Array();
var firstFlush = true;
var flushTimeout = 0;
var storedWindowHeight = 340;
/**
* MessagingWidgetsChatConversation_init:
*
* Called when the page has actually been loaded.
* Acts as a "constructor", could be used for creating the template item and
* getting the element where we will add the children in the page.
*
* However, creating such template items doesn't seem so simple, we would
* need several of them in order to be able to keep it really usable.
**/
function MessagingWidgetsChatConversation_init ()
{
/* Setting onscroll handler to window */
window.onscroll = MessagingWidgetsRenderer_onScroll;
/* Setting onresize handler to window */
window.onresize = MessagingWidgetsRenderer_onResize;
if (!markupTemplateSelf)
{
markupTemplateSelf = document.getElementById("MessageContainerSelf");
markupTemplateSelf.parentNode.removeChild(markupTemplateSelf);
markupTemplateSelf.removeAttribute('id');
markupTemplateOther = document.getElementById("MessageContainerOther");
markupTemplateOther.parentNode.removeChild(markupTemplateOther);
markupTemplateOther.removeAttribute('id');
markupTemplateNotice = document.getElementById("MessageContainerNotice");
markupTemplateNotice.parentNode.removeChild(markupTemplateNotice);
markupTemplateNotice.removeAttribute('id');
markupTemplateAction = document.getElementById(
"MessageContainerAction");
markupTemplateAction.parentNode.removeChild(
markupTemplateAction);
markupTemplateAction.removeAttribute('id');
markupTemplateAutoReply = document.getElementById("MessageContainerAutoReply");
markupTemplateAutoReply.parentNode.removeChild(markupTemplateAutoReply);
markupTemplateAutoReply.removeAttribute('id');
}
}
function MessagingWidgetsRenderer_avatarBorderClicked (event)
{
alert(event.currentTarget.id);
event.returnValue = true;
event.cancelBubble = false;
}
/*
* Fixes presence...
*/
function
MessagingWidgetsRenderer_fixPresence (
self, presence_img, presence, contact_info_str, add_to_top)
{
var presenceID;
if (!presence_img) return;
presenceID = "PresenceImg" + contact_info_str;
if (!self) {
presence_img.id = presenceID;
if (presence != null && presence != "") {
presence_img.src = presence;
}
/* Find current presence anchor in document */
var prevPresence = document.getElementById (presenceID);
if (add_to_top) {
/* If we are adding a history, check if presence anchor is
* already present in document (presumably added at bottom
* from pending messages) or in pastPresenceAnchor which
* remebers if we already created the anchor (it should
* not be re-created if already created when populating
* history).
*/
if (prevPresence ||
pastPresenceAnchor[contact_info_str] == true) {
/*
* Presence is already anchored; remove it from this item.
*/
presence_img.parentNode.removeChild (presence_img);
} else{
/*
* There is no anchor found, either in document or in
* previously anchored, so leave presence node intact
* in this item and record that anchor is already set.
*/
pastPresenceAnchor[contact_info_str] = true;
}
} else {
/* If we found a previous presence icon, we remove that.
* this one replaces the anchor
*/
if (prevPresence) {
prevPresence.parentNode.removeChild (prevPresence);
}
}
} else if (presence_img) {
presence_img.parentNode.removeChild (presence_img);
}
}
/**
* MessagingWidgetsRenderer_messagePress:
* @event: The message.
*
* Handles onMousePress event and emits the event upwards to C-code via alert()
**/
function MessagingWidgetsRenderer_messagePress (event)
{
var idstr;
idstr = "file://pre-id:"+event.currentTarget.id;
alert(idstr);
event.returnValue = true;
/* Canceling bubble so body onmousedown isn't called */
event.cancelBubble = true;
}
/**
* MessagingWidgetsRenderer_messageNode:
* @item: The message.
* @add_to_top: Add the new message to the top of the list
*
* Creates a message node
**/
function
MessagingWidgetsRenderer_messageNode (item, add_to_top)
{
/* Top level items */
var new_message;
var new_message_template;
/* Avatar data */
var avatar_img;
var avatar_img_border;
/* The graphics */
var bubble_cell;
/* Presence icon and name area */
var presence_img;
var name_tag;
/* Message text content */
var message_txt;
/* Time stamps and potential icons */
var time_tag;
var delivery_time_tag;
var business_img;
var type_name;
var count;
if (!markupTemplateSelf) {
MessagingWidgetsChatConversation_init ();
}
if (item.type == 2) {
new_message_template = markupTemplateNotice;
type_name = "Notice";
} else if (item.type == 1) {
new_message_template = markupTemplateAction;
type_name = "Action";
} else if (item.type == 3) {
new_message_template = markupTemplateAutoReply;
type_name = "AutoReply";
} else {
if (item.self) {
new_message_template = markupTemplateSelf;
type_name = "Self";
} else {
new_message_template = markupTemplateOther;
type_name = "Other";
}
}
new_message = new_message_template.cloneNode(true);
if (item.id_str == null || item.id_str == "") {
item.id_str = "GeneratedId_" + fakeid++;
}
new_message.id = "Message" + item.id_str;
new_message.onmousedown = MessagingWidgetsRenderer_messagePress;
/* Retrieve the elements to update */
var node_tags = new_message.getElementsByTagName('*');
for (var i = 0; i < node_tags.length; i++) {
if (node_tags[i].hasAttribute('id')) {
var id = node_tags[i].getAttribute('id');
if (id == ("AvatarImg" + type_name))
avatar_img = node_tags[i];
if (id == ("AvatarImgBorder" + type_name))
avatar_img_border = node_tags[i];
if (id == ("Message" + type_name))
bubble_cell = node_tags[i];
if (id == ("MessagePresence" + type_name))
presence_img = node_tags[i];
if (id == ("MessageSenderName" + type_name))
name_tag = node_tags[i];
if (id == ("MessageText" + type_name))
message_txt = node_tags[i];
if (id == ("MessageTimeStamp" + type_name))
time_tag = node_tags[i];
}
}
/* Setting sender's name color */
if (item.type == 1) {
if (item.self) {
name_tag.className += " AccentColor2";
} else {
name_tag.className += " AccentColor1";
}
}
bubble_cell.id = item.id_str;
message_txt.id = "MessageText" + item.id_str;
if (avatar_img) avatar_img.id = "avatar:" + item.contact_info_str;
if (avatar_img_border) avatar_img_border.id = "avatar:" + item.contact_info_str;
if (name_tag) name_tag.id = "MessageSenderName" + item.id_str;
if (time_tag) time_tag.id = "MessageTimeStamp" + item.id_str;
/* Creation of an avatar image */
if (avatar_img) {
avatar_img.src = item.avatar;
}
if (avatar_img_border) {
avatar_img_border.onclick =
MessagingWidgetsRenderer_avatarBorderClicked;
}
if (item.name_str != "" && name_tag) {
name_tag.innerHTML = item.name_str;
}
message_txt.innerHTML = item.message_str.replace(/\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
message_txt.setAttribute("dir", item.text_dir);
if (time_tag) {
time_tag.style.display = myShowTimes;
time_tag.innerHTML = item.time_str;
}
/* Show the new message */
new_message.style.display = "block";
/* FIXME: Move it somewhere appropriate */
MessagingWidgetsRenderer_fixPresence(item.self, presence_img, item.presence,
item.contact_info_str, add_to_top);
return new_message;
}
/**
* MessagingWidgetsRenderer_messageObject:
* @type: Type of the message (normal/action/notice/autoreply)
* @time_str: The time string to show in the screen
* @delivery_str: The delivery time string to possibly show in the screen
* @name_str: The name string to show in the screen
* @message_str: The actual message to show
* @self: TRUE if message is from self
* @id_str: The ID of the message for access
* @avatar: path(/url?) to avatar image
* @presence: presence icon of sender
* @business_icon: path to business card icon
* @status_icon: path to message status icon (pending/failed)
* @contact_info_str: Additional contact information
* @text_dir: Text direction ("ltr" or "rtl")
*
* Creates a message object.
**/
function
MessagingWidgetsRenderer_messageObject (
type, time_str, delivery_str, name_str, message_str, self, id_str,
avatar, presence, business_icon, status_icon, contact_info_str, text_dir)
{
this.type = type;
this.time_str = time_str;
this.delivery_str = delivery_str;
this.name_str = name_str;
this.message_str = message_str;
this.self = self;
this.id_str = id_str;
this.avatar = avatar;
this.presence = presence;
this.business_icon = business_icon;
this.status_icon = status_icon;
this.contact_info_str = contact_info_str;
this.text_dir = text_dir;
}
/*
* Flushes the given amount of messages from the buffer to renderer
*/
function
MessagingWidgetsRenderer_flushBuffer (amount)
{
if (messagesBuffer.length > 0) {
if (amount < 0)
amount = messagesBuffer.length;
var fragment = document.createDocumentFragment();
for (var i = 0; i < amount; i++) {
if (messagesBuffer.length <= 0)
break;
var item = messagesBuffer.shift();
new_message =
MessagingWidgetsRenderer_messageNode (item, true);
if (fragment.childNodes.length > 0)
fragment.insertBefore(new_message, fragment.firstChild);
else
fragment.appendChild(new_message);
}
/* Restore scroll position */
var savedScrollPos =
document.body.scrollHeight - window.pageYOffset;
document.body.insertBefore(fragment, document.body.firstChild);
window.sizeToContent();
window.scrollTo(0, (document.body.scrollHeight - savedScrollPos));
}
}
/* Scroll event handler to potentially add more past history */
function
MessagingWidgetsRenderer_onScroll (event)
{
/* Buffer flushing if there isn't already one running. */
if (window.pageYOffset < 100 && messagesBuffer.length > 0) {
/* Add a page of messages (about 4 screen-full) to renderer */
MessagingWidgetsRenderer_flushBuffer(HISTORY_PAGE_SIZE);
}
/* If we run out of messages in buffer and history hasn't finished,
* request for more
*/
if (messagesBuffer.length == 0 &&
myBatchRequested == HISTORY_FETCHING_NOREQUEST) {
myBatchRequested = HISTORY_BATCH_SIZE;
alert("history-request:" + HISTORY_BATCH_SIZE);
}
}
/* When conversation view editor expands/shrinks, scroll accordingly to */
/* keep the the bottom position of the screen fixed. */
function
MessagingWidgetsRenderer_onResize (event)
{
if (Math.abs(storedWindowHeight - window.innerHeight) != 0) {
window.scrollBy(0, storedWindowHeight - window.innerHeight);
storedWindowHeight = window.innerHeight;
}
}
/**
* MessagingWidgetsRenderer_addMessage:
* @type: Type of the message (normal/action/notice/autoreply)
* @time_str: The time string to show in the screen
* @delivery_str: The delivery time string to possibly show in the screen
* @name_str: The name string to show in the screen
* @message_str: The actual message to show
* @self: TRUE if message is from self
* @id_str: The ID of the message for access
* @avatar: path(/url?) to avatar image
* @presence: presence icon of sender
* @business_icon: path to business card icon
* @status_icon: path to message status icon (pending/failed)
* @contact_info_str: Additional contact information
* @add_to_top: Add the new message to the top of the list
* @text_dir: Text direction ("ltr" or "rtl")
*
* Queues messages to buffer and triggers flush schedule. Also forces
* an immediate flush if there are 5 messages already in buffer for
* the first time. It's a screenful of messages shown to the user in
* first opportunity.
**/
function
MessagingWidgetsRenderer_addMessage (
type, time_str, delivery_str, name_str, message_str, self, id_str,
avatar, presence, business_icon, status_icon, contact_info_str, add_to_top,
text_dir)
{
var item =
new MessagingWidgetsRenderer_messageObject (type, time_str,
delivery_str,
name_str, message_str,
self, id_str, avatar,
presence, business_icon,
status_icon,
contact_info_str,
text_dir);
if (add_to_top) {
/* Queue the top (history) message in buffer. */
messagesBuffer[messagesBuffer.length] = item;
/* Force flush if there's already screenful of messages to show for
* the first time.
*/
if (firstFlush == true &&
messagesBuffer.length >= HISTORY_SCREENFULL_SIZE) {
firstFlush = false;
MessagingWidgetsRenderer_flushBuffer(HISTORY_SCREENFULL_SIZE);
}
} else {
/* If the message is bottom, add it directly without queuing. */
var new_message =
MessagingWidgetsRenderer_messageNode (item, false);
document.body.appendChild (new_message);
window.sizeToContent();
/* scrolling to new message, if the view is close to bottom, or */
/* sent by self. If not, we don't scroll */
if (document.body.scrollHeight - window.pageYOffset < 640 || self) {
new_message.scrollIntoView (false);
}
}
}
/**
* MessagingWidgetsRenderer_batchAdded:
* @messages_fetched: Number of messages fetched from log
*
* History batch has been added to renderer
**/
function MessagingWidgetsRenderer_batchAdded (messages_fetched)
{
/* Force flush if there hasn't been anything shown yet.
* This happens because the first batch was smaller than
* HISTORY_SCREENFULL_SIZE.
*/
if (firstFlush == true && messagesBuffer.length >= 0) {
firstFlush = false;
MessagingWidgetsRenderer_flushBuffer(-1);
}
/* If there was no request made, then it's the first batch pushed.
* The subsequent batch is requested after a delay of 1s to allow
* first screenfull to be rendered properly.
*/
if (myBatchRequested == HISTORY_FETCHING_NOREQUEST) {
if (flushTimeout != 0)
clearTimeout(flushTimeout);
flushTimeout = setTimeout("MessagingWidgetsRenderer_onScroll();",
1000);
} else if (myBatchRequested > 0) {
/* If there was a request, check if we got everything.
* If received messages is the amount requested, we could
* continue fetching more, otherwise there is no more history
* to fetch.
*/
if (messages_fetched < myBatchRequested) {
myBatchRequested = HISTORY_FETCHING_DONE; /* No more history */
} else {
myBatchRequested = HISTORY_FETCHING_NOREQUEST; /* Batch delivered */
}
/* Check if anything needs to be rendered at this scroll position */
MessagingWidgetsRenderer_onScroll();
}
}
/**
* MessagingWidgetsRenderer_deleteMessage:
* @id_str: The ID of the message to delete
*
* Removes a message from the message area
**/
function MessagingWidgetsRenderer_deleteMessage (id_str)
{
var txt;
var node = null;
MessagingWidgetsDebug_print (
"MessagingWidgetsRenderer_deleteMessage("+id_str+") called.");
txt = "Message"+id_str;
node = document.getElementById(txt);
if (node == null) {
MessagingWidgetsDebug_print ("No messages with id: " + id_str);
return;
}
try {
document.body.removeChild (node);
window.scrollBy (0,0);
} catch (e) {
MessagingWidgetsDebug_print (
"Message " + index + " removal failed: " + e);
}
return;
}
/**
* MessagingWidgetsRenderer_showDeliveryTimes:
* @visibility: Set to 'inline' to show delivery time stamps. Set to
* 'none' not to show them.
*
* Set if delivery time stamps should be visible
**/
function MessagingWidgetsRenderer_showDeliveryTimes (visibility)
{
var times;
if (visibility != "inline" && visibility != "none") {
MessagingWidgetsDebug_print(
"MessagingWidgetsRenderer_showDeliveryTimes: Illegal parameter: "
+ visibility);
return;
}
myShowTimes = visibility;
times = document.getElementsByTagName("span");
if (times == null) {
return;
}
MessagingWidgetsDebug_print("span elements: "+times.length);
for (i = 0; i < times.length; i++) {
if (times[i].className.indexOf ("MessageDeliveryTimeStamp") != -1) {
times[i].style.display = myShowTimes;
}
}
return;
}
/**
* MessagingWidgetsRenderer_setTimes:
* @id_str: id of the message
* @time_str: message time stamp
* @delivery_str: message delivery time stamp
* @status_icon: path+name of a status icon (pending/failed)
*
* Set time stamps and status icon
**/
function MessagingWidgetsRenderer_setTimes (id_str, time_str, delivery_str,
status_icon)
{
var icon;
// Weird new browser behaviour here. Looks like if the src of the status
// icon is set to not valid icon value, the browser keeps displaying the old
// valid icon. Only when you put to the src a valid icon does it change.
// Worked around this by hiding the image altogether if the icon is set
// to "".
icon = document.getElementById("MessageStatusImg"+id_str);
if (icon != null) {
icon.src = status_icon;
if (status_icon == "") {
icon.style.display = "none";
} else {
icon.style.display = "inline";
}
}
document.getElementById("MessageTimeStamp"+id_str).innerHTML = time_str;
document.getElementById("MessageDeliveryTimeStamp"+id_str).innerHTML =
delivery_str;
return;
}
/**
* MessagingWidgetsRenderer_setPresence:
* @contact_info: The contact info for presence icon
* @presence: Presence icon path
*
* Sets the presence icon of @contact_info to @presence
**/
function MessagingWidgetsRenderer_setPresence (contact_info, presence)
{
var presenceImg = document.getElementById ("PresenceImg" + contact_info);
if (presenceImg != null) {
presenceImg.src = presence;
} else {
/* Find in buffer */
for (var i = 0; i < messagesBuffer.length; i++) {
if (messagesBuffer[i].contact_info_str == contact_info) {
messagesBuffer[i].presence = presence;
break;
}
}
}
}
/**
* MessagingWidgetsRenderer_setMaxMessages:
* @max: maximum number of messages
*
* Sets the maximum number of messages (default is 50)
**/
function MessagingWidgetsRenderer_setMaxMessages (max)
{
var count;
myMaxMessages = max;
count = document.body.childNodes.count;
if (count >= myMaxMessages) {
var i;
for (i = count - myMaxMessages + 1; i > 0; i--) {
document.body.removeChild (document.body.firstChild);
}
}
return;
}
/**
* MessagingWidgetsRenderer_setCSS:
* @file: Path of theme CSS file
*
* Sets the system theme CSS file to the current page.
*
**/
function MessagingWidgetsRenderer_setCSS (file)
{
document.getElementById("ThemeCSSLink").href = file;
return;
}
/**
* MessagingWidgetsRenderer_setTheme:
* @theme: Theme name to set
*
* Sets the user theme.
*
**/
function MessagingWidgetsRenderer_setTheme (theme)
{
if (!theme || theme == '')
document.getElementById("ThemeCSSLinkUser").href = "";
else
document.getElementById("ThemeCSSLinkUser").href = theme + "/theme.css";
}
/**
* MessagingWidgetsRenderer_addBatch:
*
* @messages: Array of messages to add
*
* Adds several messages to view
*
**/
function MessagingWidgetsRenderer_addBatch (messages)
{
var len = messages.length;
var i;
// starting from 1, because of the extra ',' at the beginning due to
// performance optimizations
for(i=1; i<len; i++) {
// Calling addMessage for each batched call. Converting strings
// representing bool/int parameters
MessagingWidgetsRenderer_addMessage(Number(messages[i][0]),
messages[i][1], messages[i][2], messages[i][3], messages[i][4],
(messages[i][5] === 'true'), messages[i][6], messages[i][7],
messages[i][8], messages[i][9], messages[i][10], messages[i][11],
(messages[i][12]) === 'true', messages[i][13]);
}
return;
}
/**
* @file MessagingWidgetsDebug.jsm
*
* A Debugger helper for javascripts in rtcom-messaging-ui. Define the
* myDebug to non-zero for the debugging functions to work
*/
/*
* This file is part of rtcom messaging ui
*
* Copyright (C) 2009 Nokia Corporation. All rights reserved.
*
* Contact: Naba Kumar <naba.kumar@nokia.com>
*
* This software, including documentation, is protected by copyright
* controlled by Nokia Corporation. All rights are reserved.
* Copying, including reproducing, storing, adapting or translating,
* any or all of this material requires the prior written consent of
* Nokia Corporation. This material also contains confidential
* information which may not be disclosed to others without the prior
* written consent of Nokia.
*/
/** Define to non-zero to debug the Javascripts */
var myDebug = 0;
/**
* MessagingWidgetsDebug_print:
* @param message The message to print
*
* Returns immediately if @myDebug is set to 0
*/
function
MessagingWidgetsDebug_print (message)
{
if (!myDebug) return;
if (!message) return;
try {
window.dump (message + "\n");
} catch (e) {
/* XXX: Just to be sure the debugging function doesn't cause an
* error in JS execution
*/
}
}
/**
* Style rules for the MessageBuffer
*/
/**
* the body defaults
*/
body {
word-wrap: break-word;
margin-left: 16px;
margin-right: 16px;
vertical-align: top;
}
/**
* The table column formats
*/
div.Message * {
white-space: normal;
}
#MessagingArea {
vertical-align: top;
}
div.Message {
clear: both;
white-space: nowrap;
vertical-align: middle;
}
div.Message.Self {
}
div.Message.Other {
}
div.Message:first-child {
padding-top: 0px;
}
div.Message:last-child {
padding-bottom: 0px;
}
div.BubbleSelf {
vertical-align: top;
width: 100%;
display: inline-block;
}
div.MessageContainerOther {
}
div.BubbleOther {
vertical-align: top;
width: 100%;
display: inline-block;
}
/**
* Others' Avatars
*
* This needs a "drop down" shadow, but no idea if that can be done
*Adele: please note that this drop down shadow might be subjected to change
*I've talked about it with Vilja who's in charge of address book layout
*and we might change it so that it's a double border colour to indicate
*that the avatar is clickable. drop shawdow doesn't seem to work with
*dark backgrounds unless it's a light colour drop shadow.
*PLEASE tell me if it's difficult to implement the drop shadow.
*/
div.Avatar {
margin: 0px 16px 0px 0px; /* top right bottom left */
padding: 8px 0px;
width: 80px;
display: inline-block;
vertical-align: top;
}
.MessageAvatar {
width: 80px;
height:80px;
outline-style: solid;
outline-width: 4px;
-moz-outline-radius: 8px;
}
div.MessageAvatarBorder {
z-index: 1;
width: 80px;
height: 80px;
position: absolute;
top: 15px;
left: 15px;
display: inline-block;
-moz-border-radius: 6px;
border-width: 1px;
border-style: solid;
}
div.MessagePresenceBox {
width: 24px;
padding: 8px 0px;
display: inline-block;
vertical-align: top;
}
span.MessagePresence {
width: 24px;
display: inline-block;
}
img.MessagePresence {
vertical-align: middle;
width: 16px;
height: 16px;
}
/**
* the Name field
*/
span.MessageNameField {
word-wrap: break-word;
vertical-align: middle;
padding: 0px;
margin: 0px;
}
span.MessageNameField.Self {
}
span.MessageNameField.Other {
}
/**
* the Text field
*/
div.MessageText {
border-top-style: solid;
border-top-width: 2;
padding-top: 8px;
margin-top: 8px;
display: block;
text-align: left;
vertical-align: middle;
word-wrap: break-word;
}
.MessageText.Other {
width: 100%;
}
.MessageText.Self {
width: 100%;
}
/**
* the NameSeparator field
*/
span.MessageNameSeparator {
vertical-align: middle;
}
.MessageSeparator {
visibility: hidden;
}
/**
* the TimeStamp default rules
*/
div.MessageTop {
margin-bottom: 8px;
white-space: nowrap;
}
div.MessageTop.Self {
}
div.MessageTop.Other {
display: block;
}
img.MessageBusinessCardImg {
vertical-align: middle;
padding-right: 4px;
}
span.MessageTimeStamp {
}
span.MessageDeliveryTimeStamp {
}
img.MessageStatusImg {
vertical-align: middle;
padding-right: 0px;
}
.MessagingWidgetsSmiley {
height: 24px;
width: 24px;
}
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- messaging-widgets -->
<html>
<head>
<link rel="stylesheet" type="text/css" href="MessagingWidgetsSingleSMS.css"></link>
<link rel="stylesheet" type="text/css" href="/etc/hildon/theme/css/colors.css" id="ThemeCSSLink"></link>
<script type="text/javascript" src="MessagingWidgetsSingleSMS.js" charset="UTF-8"></script>
</head>
<!-- Preserve the tag IDs. Everything else can be changed and rearranged -->
<body class="nodebug DefaultBackgroundColor DefaultTextColor SystemFont" onload="MessagingWidgetsSingleSMS_init()">
<div id="MessagingArea">
<div id="MessageContainerSelf" class="Message Self" style="display:none;">
<div id="MessageSelf" class="BubbleSelf">
<div class="MessageTop Self">
<div id="MessageSenderNameSelf" class="MessageNameField SecondaryTextColor LargeSystemFont Self"></div>
<img id="MessageBusinessCardImgSelf" class="MessageBusinessCardImg" src=""/>
<span id="MessageTimeStampSelf" class="MessageTimeStamp SecondaryTextColor Self SmallSystemFont"></span>
<span id="MessageDeliveryTimeStampSelf" class="MessageDeliveryTimeStamp PrimaryTextColor Self SmallSystemFont"></span>
<span id="MessageStatusSelf" class="MessageStatus PrimaryTextColor"></span>
</div>
<div id="MessageTextSelf" class="MessageText Self MessagingBubbleBorderColor"></div>
</div>
</div>
<div id="MessageContainerOther" class="Message Other" style="display:none;">
<div id="MessageOther" class="BubbleOther">
<div class="Avatar">
<div id="AvatarImgBorderOther" class="MessageAvatarBorder Other MessagingAvatarBorderColor"></div>
<img id="AvatarImgOther" src="" class="MessageAvatar MessagingAvatarBorderMaskColor " />
</div>
<div style="display:inline-block;">
<div id="MessagePresenceBoxOther" class="MessagePresenceBox">
<span class="MessagePresence"><img id="MessagePresenceOther" src="" class="MessagePresence"/></span>
</div>
<span id="MessageSenderNameOther" class="MessageNameField SecondaryTextColor LargeSystemFont Other"></span>
<div class="MessageTop Other">
<img id="MessageBusinessCardImgOther" class="MessageBusinessCardImg" src=""/>
<span id="MessageTimeStampOther" class="MessageTimeStamp SecondaryTextColor Other SmallSystemFont"></span>
<span id="MessageDeliveryTimeStampOther" class="MessageDeliveryTimeStamp PrimaryTextColor Other SmallSystemFont"></span>
<span id="MessageStatusOther" class="MessageStatus PrimaryTextColor"></span>
</div>
</div>
<div id="MessageTextOther" class="MessageText Other MessagingBubbleBorderColor"></div>
</div>
</div>
</div>
</body>
</html>
/**
* @file MessagingWidgetsSingleSMS.js
*
* Javascript for messaging rendering widget's ring buffer.
*/
/*
* This file is part of rtcom messaging ui
*
* Copyright (C) 2009 Nokia Corporation. All rights reserved.
*
* Contact: Naba Kumar <naba.kumar@nokia.com>
*
* This software, including documentation, is protected by copyright
* controlled by Nokia Corporation. All rights are reserved.
* Copying, including reproducing, storing, adapting or translating,
* any or all of this material requires the prior written consent of
* Nokia Corporation. This material also contains confidential
* information which may not be disclosed to others without the prior
* written consent of Nokia.
*/
/**
* Globals:
*
* @myShowTimes: Display method for time stamps, set to 'inline' to show
* and 'none' to hide
*
**/
var myShowTimes = "inline";
var markupTemplateSelf;
var markupTemplateOther;
/**
* MessagingWidgetsSingleSMS_init:
*
**/
function MessagingWidgetsSingleSMS_init ()
{
if (!markupTemplateSelf)
{
markupTemplateSelf = document.getElementById("MessageContainerSelf");
markupTemplateSelf.parentNode.removeChild(markupTemplateSelf);
markupTemplateSelf.removeAttribute('id');
markupTemplateOther = document.getElementById("MessageContainerOther");
markupTemplateOther.parentNode.removeChild(markupTemplateOther);
markupTemplateOther.removeAttribute('id');
}
}
function MessagingWidgetsRenderer_avatarClicked (event)
{
alert(event.currentTarget.id);
event.returnValue = true;
event.cancelBubble = false;
}
/**
* MessagingWidgetsRenderer_addMessage:
*
* @type: Type of the message (normal/action/notice/autoreply)
* @time_str: The time string to show in the screen
* @delivery_str: The delivery time string to possibly show in the screen
* @name_str: The name string to show in the screen
* @message_str: The actual message to show
* @self: TRUE if message is from self
* @id_str: The ID of the message for access
* @avatar: path(/url?) to avatar image
* @presence: presence icon of sender
* @business_icon: path to business card icon
* @status_text: message status text (delivered/on the way/delivery failed)
* @contact_info_str: Additional contact information
* @add_to_top: unused in single SMS view
* @text_dir: Text direction ("ltr" or "rtl")
*
* Adds messages to the message area.
* Note that unlike other views, message status is indicated as text,
* not as an icon.
**/
function
MessagingWidgetsRenderer_addMessage (
type, time_str, delivery_str, name_str, message_str, self, id_str,
avatar, presence, business_icon, status_text, contact_info_str, add_to_top,
text_dir)
{
/* Top level items */
var new_message;
/* Avatar data */
var avatar_img;
var avatar_img_border;
/* The graphics */
var bubble_cell;
/* Presence icon and name area */
var presence_img;
var presence_box;
var name_tag;
/* Message text content */
var message_txt;
/* Time stamps and potential icons */
var time_tag;
var delivery_time_tag;
var business_img;
var status_span;
var party;
var count;
if (!markupTemplateSelf)
{
markupTemplateSelf = document.getElementById("MessageContainerSelf");
markupTemplateSelf.parentNode.removeChild(markupTemplateSelf);
markupTemplateSelf.removeAttribute('id');
markupTemplateOther = document.getElementById("MessageContainerOther");
markupTemplateOther.parentNode.removeChild(markupTemplateOther);
markupTemplateOther.removeAttribute('id');
}
if (type != 0) {
alert("Only type 0 is allowed");
return;
}
if (self == true) {
party = "Self";
new_message = markupTemplateSelf.cloneNode(true);
/* Finally, append the whole message to the document */
new_message.id = "Message" + id_str;
document.getElementById("MessagingArea").appendChild (new_message);
/* Retrieve the elements to update */
bubble_cell = document.getElementById ("Message" + party);
name_tag = document.getElementById ("MessageSenderName" + party);
business_img = document.getElementById ("MessageBusinessCardImg" + party);
message_txt = document.getElementById ("MessageText" + party);
time_tag = document.getElementById ("MessageTimeStamp" + party);
delivery_time_tag = document.getElementById ("MessageDeliveryTimeStamp" + party);
status_span = document.getElementById ("MessageStatus" + party);
} else {
party = "Other";
new_message = markupTemplateOther.cloneNode(true);
/* Finally, append the whole message to the document */
new_message.id = "Message" + id_str;
document.getElementById("MessagingArea").appendChild (new_message);
/* Retrieve the elements to update */
avatar_img = document.getElementById ("AvatarImg" + party);
avatar_img_border = document.getElementById ("AvatarImgBorder" + party);
bubble_cell = document.getElementById ("Message" + party);
presence_img = document.getElementById ("MessagePresence" + party);
presence_box = document.getElementById ("MessagePresenceBox" + party);
name_tag = document.getElementById ("MessageSenderName" + party);
business_img = document.getElementById ("MessageBusinessCardImg" + party);
message_txt = document.getElementById ("MessageText" + party);
time_tag = document.getElementById ("MessageTimeStamp" + party);
delivery_time_tag = document.getElementById ("MessageDeliveryTimeStamp" + party);
status_span = document.getElementById ("MessageStatus" + party);
avatar_img_border.id = "avatar:" + contact_info_str;
presence_img.id = "PresenceImg" + contact_info_str;
presence_box.id = "PresenceBox" + contact_info_str;
}
bubble_cell.id = id_str;
message_txt.id = "MessageText" + id_str;
name_tag.id = "MessageSenderName" + id_str;
business_img.id = "MessageBusinessCardImg" + id_str;
time_tag.id = "MessageTimeStamp" + id_str;
delivery_time_tag.id = "MessageDeliveryTimeStamp" + id_str;
status_span.id = "MessageStatus" + id_str;
message_txt.setAttribute("dir", text_dir);
/* Creation of an avatar image */
if (self == false) {
if (avatar != "") {
avatar_img.src = avatar;
}
avatar_img_border.onclick = MessagingWidgetsRenderer_avatarClicked;
}
if (self == false) {
if (presence != "") {
presence_img.src = presence;
presence_box.style.display = "inline-block";
}
else {
presence_box.style.display = "none";
}
}
message_str=message_str.replace(/\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
name_tag.textContent = name_str;
message_txt.innerHTML = message_str;
if (business_icon != "") {
business_img.src = business_icon;
}
time_str=time_str.replace(/\|/,"");
delivery_str=delivery_str.replace(/\|/,"");
time_tag.style.display = myShowTimes;
time_tag.textContent = time_str;
delivery_time_tag.style.display = myShowTimes;
if(delivery_str != "") {
delivery_time_tag.textContent = "| "+delivery_str;
}
if (status_text != "") {
status_span.textContent = status_text;
}
/* Show the new message */
new_message.style.display = "block";
/* scroll message area to the top */
window.scrollTo(0,0);
return;
}
/**
* MessagingWidgetsRenderer_showDeliveryTimes:
*
* @visibility: Set to 'inline' to show delivery time stamps. Set to
* 'none' not to show them.
*
* Set if delivery time stamps should be visible
**/
function MessagingWidgetsRenderer_showDeliveryTimes (visibility)
{
var times;
if (visibility != "inline" && visibility != "none") {
alert("MessagingWidgetsRenderer_showDeliveryTimes: Illegal parameter: "+ visibility);
return;
}
myShowTimes = visibility;
times = document.getElementsByTagName("span");
if (times == null) {
return;
}
for (i = 0; i < times.length; i++) {
if (times[i].className == "MessageDeliveryTimeStamp") {
times[i].style.display = myShowTimes;
}
}
return;
}
/**
* MessagingWidgetsRenderer_setTimes:
*
* @id_str: id of the message (ignored in case of single SMS view)
* @time_str: message time stamp
* @delivery_str: message delivery time stamp
* @status_text: message status text
*
* Set if delivery time stamps should be visible
**/
function MessagingWidgetsRenderer_setTimes (id_str, time_str, delivery_str,
status_text)
{
var msg;
time_str=time_str.replace(/\|/,"");
delivery_str=delivery_str.replace(/\|/,"");
status_span = document.getElementById("MessageStatus"+id_str);
if (status_span != null) {
status_span.textContent = status_text;
}
document.getElementById("MessageTimeStamp"+id_str).textContent = time_str;
if(delivery_str != "") {
document.getElementById("MessageDeliveryTimeStamp"+id_str).textContent =
"| "+delivery_str;
}
return;
}
/**
* MessagingWidgetsRenderer_setPresence:
* @contact_info: The contact info for presence icon
* @presence: Presence icon path
*
* Sets the presence icon of @contact_info to @presence
**/
function MessagingWidgetsRenderer_setPresence (contact_info, presence)
{
var presenceImg = document.getElementById ("PresenceImg" + contact_info);
var presenceBox = document.getElementById ("PresenceBox" + contact_info);
if (presenceImg != null) {
presenceImg.src = presence;
presenceBox.style.display = "inline-block";
}
else {
presenceBox.style.display = "inline-block";
}
}
/**
* MessagingWidgetsRenderer_setCSS:
*
* @file: Path of theme CSS file
*
* Sets the theme CSS file to the current page.
*
**/
function MessagingWidgetsRenderer_setCSS (file)
{
document.getElementById("ThemeCSSLink").href = file;
MessagingWidgetsSMSConversation_alert("set: "+file+" as theme CSS file.");
return;
}
/**
* Style rules for the MessageBuffer
*/
/**
* the body defaults
*/
body {
margin-left: 16px;
margin-right: 16px;
font-size: 5px !important;
}
.MessageTimeStamp {
font-family: monospace !important;
}
/**
* The table column formats
*/
div.Message {
padding-bottom: 8px;
display: table;
width: 100%;
display: inline !important;
}
div.Message.Other {
padding-left: 6px;
}
div.Message:first-child {
padding-top: 0px;
}
div.Message:last-child {
padding-bottom: 0px;
}
div.BubbleSelf {
-moz-border-radius: 4px 4px 4px 4px;
border-style: solid;
border-width: 1px;
padding: 4px 8px;
margin-right: 0px;
margin-left: 0px;
// display: table-cell;
/* overflow: hidden; this bugs mouse events. see bug #123077 */
}
div.BubbleOther {
-moz-border-radius: 6px ;
border-style: solid;
border-width: 1px;
margin-left: 0px;
margin-right: 0px;
vertical-align: middle;
padding: 4px 8px;
// display: table-cell;
min-height: 56px;
/* overflow: hidden; this bugs mouse events. see bug #123077 */
margin-right: 4px;
}
div.BubbleSpacer {
padding: 0px;
margin: 0px;
vertical-align: middle;
// display: table-cell;
height: 52px;
}
div.BubbleSelfClicked {
-moz-border-radius: 4px 4px 4px 4px;
border-style: solid;
border-width: 1px;
padding: 4px 8px;
text-shadow: 0.1em 0.1em #000;
// display: table-cell;
/* overflow: hidden; this bugs mouse events. see bug #123077 */
}
div.BubbleOtherClicked {
-moz-border-radius: 6px ;
border-style: solid;
border-width: 1px;
text-shadow: 0.1em 0.1em #000;
vertical-align: middle;
padding: 4px 8px;
// display: table-cell;
min-height: 56px;
/* overflow: hidden; this bugs mouse events. see bug #123077 */
}
/**
* Others' Avatars
*
* This needs a "drop down" shadow, but no idea if that can be done
*Adele: please note that this drop down shadow might be subjected to change
*I've talked about it with Vilja who's in charge of address book layout
*and we might change it so that it's a double border colour to indicate
*that the avatar is clickable. drop shawdow doesn't seem to work with
*dark backgrounds unless it's a light colour drop shadow.
*PLEASE tell me if it's difficult to implement the drop shadow.
* Looks like drop shadow is dropped from ui specs. And bug 139130 made me
*remove the space for it anyway.
*/
div.Avatar {
display: none;
vertical-align: middle;
padding-right: 2px;
width: 64px;
}
.MessageAvatar {
width: 64px;
height:64px;
border: 1px solid; /* #9e9e9e; */
-moz-border-radius: 6px;
}
img.MessagePresence {
vertical-align: middle;
width: 16px;
height: 16px;
}
/**
* the Name field
*/
span.MessageNameField {
word-wrap: break-word;
vertical-align: middle;
}
/**
* the Text field
*/
span.MessageText {
text-align: left;
vertical-align: middle;
word-wrap: break-word;
}
/**
* the TimeStamp default rules
*/
div.MessageRight {
float: right;
padding-left: 16px;
white-space: nowrap;
text-align: right;
text-size: 10px;
}
img.MessageBusinessCardImg {
vertical-align: middle;
padding-right: 4px;
}
img.MessageStatusImg {
vertical-align: middle;
padding-right: 8px;
}
.MessagingWidgetsSmiley {
height: 24px;
width: 24px;
}
/**
* Style rules for the MessageBuffer
*/
/**
* the body defaults
*/
body {
margin-left: 16px;
margin-right: 16px;
}
/**
* The table column formats
*/
div.Message {
padding-bottom: 8px;
clear: both;
display: block;
}
div.Message.Other {
padding-left: 12px;
}
div.Message:first-child {
padding-top: 0px;
}
div.Message:last-child {
padding-bottom: 0px;
}
div.BubbleSelf {
-moz-border-radius: 4px 4px 4px 4px;
border-style: solid;
border-width: 1px;
padding: 4px 8px;
margin-right: 0px;
margin-left: 0px;
display: inline-block;
width: 732px;
/* overflow: hidden; this bugs mouse events. see bug #123077 */
}
div.BubbleOther {
-moz-border-radius: 6px ;
border-style: solid;
border-width: 1px;
margin-left: 0px;
margin-right: 0px;
vertical-align: middle;
padding: 4px 8px;
display: inline-block;
width: 664px;
min-height: 56px;
/* overflow: hidden; this bugs mouse events. see bug #123077 */
}
div.BubbleSpacer {
padding: 0px;
margin: 0px;
vertical-align: middle;
display: table-cell;
width: 664px;
max-width: 664px;
height: 52px;
}
div.BubbleSelfClicked {
-moz-border-radius: 4px 4px 4px 4px;
border-style: solid;
border-width: 1px;
padding: 4px 8px;
text-shadow: 0.1em 0.1em #000;
display: inline-block;
width: 732px;
/* overflow: hidden; this bugs mouse events. see bug #123077 */
}
div.BubbleOtherClicked {
-moz-border-radius: 6px ;
border-style: solid;
border-width: 1px;
text-shadow: 0.1em 0.1em #000;
vertical-align: middle;
padding: 4px 8px;
display: inline-block;
width: 664px;
min-height: 56px;
/* overflow: hidden; this bugs mouse events. see bug #123077 */
}
/**
* Others' Avatars
*
* This needs a "drop down" shadow, but no idea if that can be done
*Adele: please note that this drop down shadow might be subjected to change
*I've talked about it with Vilja who's in charge of address book layout
*and we might change it so that it's a double border colour to indicate
*that the avatar is clickable. drop shawdow doesn't seem to work with
*dark backgrounds unless it's a light colour drop shadow.
*PLEASE tell me if it's difficult to implement the drop shadow.
* Looks like drop shadow is dropped from ui specs. And bug 139130 made me
*remove the space for it anyway.
*/
div.Avatar {
display: inline-block;
vertical-align: middle;
}
.MessageAvatar {
width: 64px;
height:64px;
border: 1px solid; /* #9e9e9e; */
-moz-border-radius: 6px;
}
img.MessagePresence {
vertical-align: middle;
width: 16px;
height: 16px;
}
/**
* the Name field
*/
span.MessageNameField {
word-wrap: break-word;
vertical-align: middle;
}
/**
* the Text field
*/
span.MessageText {
text-align: left;
vertical-align: middle;
word-wrap: break-word;
}
/**
* the TimeStamp default rules
*/
div.MessageRight {
float: right;
padding-left: 16px;
white-space: nowrap;
text-align: right;
display: inline-block;
}
img.MessageBusinessCardImg {
vertical-align: middle;
padding-right: 4px;
}
img.MessageStatusImg {
vertical-align: middle;
padding-right: 8px;
}
.MessagingWidgetsSmiley {
height: 24px;
width: 24px;
}
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- messaging-widgets -->
<html>
<head>
<link rel="stylesheet" type="text/css" href="better.css"></link>
<script type="text/javascript" src="MessagingWidgetsSMSConversation.js"></script>
</head>
<!-- Preserve the tag IDs. Everything else can be changed and rearranged -->
<body class="DefaultBackgroundColor DefaultTextColor SystemFont" onload="MessagingWidgetsSMSConversation_init()">
<div id="MessageContainerSelf" class="Message Self">
<div id="MessageSelf" class="MessagingBubbleSelfBackgroundColor MessagingBubbleBorderColor BubbleSelf">
<div class="MessageRight Self">
<img id="MessageBusinessCardImgSelf" class="MessageBusinessCardImg" src=""/>
<span id="MessageTimeStampSelf" class="MessageTimeStamp SecondaryTextColor Self SmallSystemFont">12:30 PM</span>
<span id="MessageDeliveryTimeStampSelf" class="MessageDeliveryTimeStamp SecondaryTextColor Self SmallSystemFont"> | 1:30 PM</span>
<img id="MessageStatusImgSelf" class="MessageStatusImg" src=""/>
</div>
<span id="MessageSenderNameSelf" class="MessageNameField AccentColor2 Self"></span>
<span id="MessageTextSelf" class="MessageText Self"></span>
</div>
</div>
<div id="MessageContainerOther" class="Message Other">
<div class="Avatar">
<div id="AvatarImgOther" class="MessageAvatar MessagingAvatarBorderColor DefaultBackgroundColor "></div>
</div>
<div id="MessageOther" class="MessagingBubbleOtherBackgroundColor MessagingBubbleBorderColor BubbleOther">
<div class="BubbleSpacer">
<div class="MessageRight Other">
<img id="MessageBusinessCardImgOther" class="MessageBusinessCardImg" src=""/>
<span id="MessageTimeStampOther" class="MessageTimeStamp SecondaryTextColor Other SmallSystemFont">12:30 PM</span>
<span id="MessageDeliveryTimeStampOther" class="MessageDeliveryTimeStamp SecondaryTextColor Other SmallSystemFont"> | 1:30 PM</span>
<img id="MessageStatusImgOther" class="MessageStatusImg" src=""/>
</div>
<img id="MessagePresenceOther" src="" class="MessagePresence"/>
<span id="MessageSenderNameOther" class="MessageNameField AccentColor1 Other"></span>
<span id="MessageTextOther" class="MessageText Other"></span>
</div>
</div>
</div>
</body>
</html>
/**
* @file MessagingWidgetsSMSConversation.js
*
* Javascript for messaging rendering widget's ring buffer.
*/
/*
* This file is part of rtcom messaging ui
*
* Copyright (C) 2009 Nokia Corporation. All rights reserved.
*
* Contact: Naba Kumar <naba.kumar@nokia.com>
*
* This software, including documentation, is protected by copyright
* controlled by Nokia Corporation. All rights are reserved.
* Copying, including reproducing, storing, adapting or translating,
* any or all of this material requires the prior written consent of
* Nokia Corporation. This material also contains confidential
* information which may not be disclosed to others without the prior
* written consent of Nokia.
*/
/**
* Globals:
*
* @myBatchRequested:
* if HISTORY_FETCHING_NOREQUEST, no batch has been requested.
* if HISTORY_FETCHING_DONE, history fetching done; no more request to give.
* if > 0, request in progress and the amount requested.
*
* @myBatchesAdded: Number of message batches retrieved from log.
*
* @myShowTimes: Display method for time stamps, set to 'inline' to show
* and 'none' to hide
*
**/
var HISTORY_BATCH_SIZE = 30;
var HISTORY_PAGE_SIZE = 15;
var HISTORY_SCREENFULL_SIZE = 8;
var HISTORY_FETCHING_DONE = -1;
var HISTORY_FETCHING_NOREQUEST = 0;
var myBatchRequested = 0;
var myShowTimes = "inline";
var myBatchesAdded = 0;
var myMaxMessages = -1;
var markupTemplateSelf;
var markupTemplateOther;
var messagesBuffer = new Array();
var pastPresenceAnchor = new Array();
var firstFlush = true;
var flushTimeout = 0;
var lastClickedBubble = null;
var storedScreenHeight = 0;
var storedBottomElement;
/**
* MessagingWidgetsSMSConversation_alert:
* @str Parameter to set for alert() call
*
* Custom, error safe alert call. Apparently with some version mismatches, the
* alert() javascript function sometimes fails. This is to prevent alert()
* failure to prevent rest of the script execution.
*
* For functionality, that actually depends on alert() call to succeed this
* is not helpful, rather it's another way of creating a malfuction that is
* harder to detect.
**/
function MessagingWidgetsSMSConversation_alert(str)
{
alert(str);
}
/**
* MessagingWidgetsSMSConversation_init:
*
* Called when the page has actually been loaded.
* Acts as a "constructor", could be used for creating the template item and
* getting the element where we will add the children in the page.
*
* However, creating such template items doesn't seem so simple, we would
* need several of them in order to be able to keep it really usable.
**/
function MessagingWidgetsSMSConversation_init ()
{
/* Setting onscroll handler to window */
window.onscroll = MessagingWidgetsRenderer_onScroll;
/* Setting onresize handler to window */
window.onresize = MessagingWidgetsRenderer_onResize;
storedScreenHeight = screen.height;
storedWindowHeight = storedScreenHeight - 140;
/* setting body onmousedown for clearing stored message id on ui side */
document.body.onmousedown = MessagingWidgetsRenderer_messagePressBody;
if (!markupTemplateSelf)
{
markupTemplateSelf = document.getElementById("MessageContainerSelf");
markupTemplateSelf.parentNode.removeChild(markupTemplateSelf);
markupTemplateSelf.removeAttribute('id');
markupTemplateOther = document.getElementById("MessageContainerOther");
markupTemplateOther.parentNode.removeChild(markupTemplateOther);
markupTemplateOther.removeAttribute('id');
}
}
/**
* MessagingWidgetsRenderer_messageClicked:
* @event:
* @id:
*
* Message area clicked
**/
function MessagingWidgetsRenderer_messageClicked (event)
{
var x = event.target;
var idstr;
/* Only handle clicks on message blocks, not on URIs */
if (x.href == "" || (!x.href && !x.parentNode.href)){
}else{
return true;
}
idstr = "file://id:"+event.currentTarget.id;
MessagingWidgetsSMSConversation_alert(idstr);
MessagingWidgetsRenderer_clearHighlight(event.currentTarget.id);
event.returnValue = true;
event.cancelBubble = false;
}
function MessagingWidgetsRenderer_messagePress (event)
{
var idstr;
idstr = "file://pre-id:"+event.currentTarget.id;
MessagingWidgetsSMSConversation_alert(idstr);
/* The popup menu posted from C code seems to steal events
and when the popup is closed, the message remains highlighted.
Workaround: use a 2-second timeout to clear highlight.
*/
setTimeout("MessagingWidgetsRenderer_clearHighlight()", 2000);
event.returnValue = true;
/* Canceling bubble so body onmousedown isn't called */
event.cancelBubble = true;
}
/**
* MessagingWidgetsRenderer_messagePressBubble:
* @event: An onmousedown event
* Highlight message bubble when pressed.
*/
function MessagingWidgetsRenderer_messagePressBubble (event)
{
var block;
MessagingWidgetsRenderer_clearHighlight(event.currentTarget.id);
block = document.getElementById(event.currentTarget.id);
if (block) {
block.className = block.clickedClassName;
lastClickedBubble = block;
}
event.returnValue = true;
/* Canceling bubble so body onmousedown isn't called */
event.cancelBubble = false;
}
/**
* MessagingWidgetsRenderer_messagePressBubble:
* @event: (Usually) an onmouseup event
* Message bubble is not pressed any more - clear highlighting.
*/
function MessagingWidgetsRenderer_messageReleaseBubble (event)
{
MessagingWidgetsRenderer_clearHighlight();
event.returnValue = true;
event.cancelBubble = false;
}
/**
* MessagingWidgetsRenderer_clearHighlight:
* @elem_id: (optional) Don't clear if @elem_id is currently highlighted.
*
* Remove highlighting from highlighted element, if any.
*/
function MessagingWidgetsRenderer_clearHighlight (/* [elem_id] */)
{
if (lastClickedBubble) {
if (arguments.length >= 0) {
var elem_id = arguments[0];
var elem = document.getElementById(elem_id);
if (elem && elem == lastClickedBubble) {
return;
}
}
lastClickedBubble.className = lastClickedBubble.normalClassName;
lastClickedBubble = null;
}
}
function MessagingWidgetsRenderer_messagePressBody (event)
{
var idstr;
MessagingWidgetsSMSConversation_alert("file://pre-id:None");
event.returnValue = true;
event.cancelBubble = false;
}
function MessagingWidgetsRenderer_avatarClicked (event)
{
MessagingWidgetsSMSConversation_alert(event.currentTarget.id);
event.returnValue = true;
event.cancelBubble = false;
}
/*
* Fixes presence...
*/
function
MessagingWidgetsRenderer_fixPresence (
self, presence_img, presence, contact_info_str, add_to_top)
{
var presenceID = "PresenceImg" + contact_info_str;
if (!self) {
if (presence_img) {
presence_img.id = presenceID;
if (presence != null && presence != "") {
presence_img.src = presence;
}
/* Find current presence anchor in document */
var prevPresence = document.getElementById (presenceID);
if (add_to_top) {
/* If we are adding a history, check if presence anchor is
* already present in document (presumably added at bottom
* from pending messages) or in pastPresenceAnchor which
* remebers if we already created the anchor (it should
* not be re-created if already created when populating
* history).
*/
if (prevPresence ||
pastPresenceAnchor[contact_info_str] == true) {
/*
* Presence is already anchored; remove it from this item.
*/
presence_img.parentNode.removeChild (presence_img);
} else{
/*
* There is no anchor found, either in document or in
* previously anchored, so leave presence node intact
* in this item and record that anchor is already set.
*/
pastPresenceAnchor[contact_info_str] = true;
}
} else {
/* If we found a previous presence icon, we remove that.
* this one replaces the anchor
*/
if (prevPresence) {
prevPresence.parentNode.removeChild (prevPresence);
}
}
}
} else if (presence_img) {
presence_img.parentNode.removeChild (presence_img);
}
}
function fmtDate(str){
var dayTime = str.split(" | ");
if (dayTime.length != 2)
return str;
return dayTime[0].split("/").reverse().join("-") + " " + dayTime[1];
}
/**
* MessagingWidgetsRenderer_messageNode:
* @item: The message.
* @add_to_top: Add the new message to the top of the list
*
* Creates a message node
**/
function
MessagingWidgetsRenderer_messageNode (item, add_to_top)
{
/* Top level items */
var new_message;
/* Avatar data */
var avatar_img;
/* The graphics */
var bubble_cell;
/* Presence icon and name area */
var presence_img = null;
var name_tag;
/* Message text content */
var message_txt;
/* Time stamps and potential icons */
var time_tag;
var delivery_time_tag;
var business_img;
var status_img;
var party;
var count;
if (!markupTemplateSelf) {
MessagingWidgetsSMSConversation_init();
}
if (item.type != 0) {
MessagingWidgetsSMSConversation_alert("Only type 0 is allowed");
return;
}
if (item.self == true) {
party = "Self";
new_message = markupTemplateSelf.cloneNode(true);
/* Finally, append the whole message to the document */
new_message.id = "Message" + item.id_str;
new_message.onmousedown = MessagingWidgetsRenderer_messagePress;
/* Retrieve the elements to update */
var node_tags = new_message.getElementsByTagName('*');
for (var i = 0; i < node_tags.length; i++) {
if (node_tags[i].hasAttribute('id')) {
var id = node_tags[i].getAttribute('id');
if (id == ("AvatarImg" + party))
avatar_img = node_tags[i];
if (id == ("Message" + party))
bubble_cell = node_tags[i];
if (id == ("MessagePresence" + party))
presence_img = node_tags[i];
if (id == ("MessageSenderName" + party))
name_tag = node_tags[i];
if (id == ("MessageText" + party))
message_txt = node_tags[i];
if (id == ("MessageTimeStamp" + party))
time_tag = node_tags[i];
if (id == ("MessageBusinessCardImg" + party))
business_img = node_tags[i];
if (id == ("MessageDeliveryTimeStamp" + party))
delivery_time_tag = node_tags[i];
if (id == ("MessageStatusImg" + party))
status_img = node_tags[i];
}
}
} else {
party = "Other";
new_message = markupTemplateOther.cloneNode(true);
/* Finally, append the whole message to the document */
new_message.id = "Message" + item.id_str;
new_message.onmousedown = MessagingWidgetsRenderer_messagePress;
/* Retrieve the elements to update */
var node_tags = new_message.getElementsByTagName('*');
for (var i = 0; i < node_tags.length; i++) {
if (node_tags[i].hasAttribute('id')) {
var id = node_tags[i].getAttribute('id');
if (id == ("AvatarImg" + party))
avatar_img = node_tags[i];
if (id == ("Message" + party))
bubble_cell = node_tags[i];
if (id == ("MessagePresence" + party))
presence_img = node_tags[i];
if (id == ("MessageSenderName" + party))
name_tag = node_tags[i];
if (id == ("MessageText" + party))
message_txt = node_tags[i];
if (id == ("MessageTimeStamp" + party))
time_tag = node_tags[i];
if (id == ("MessageBusinessCardImg" + party))
business_img = node_tags[i];
if (id == ("MessageDeliveryTimeStamp" + party))
delivery_time_tag = node_tags[i];
if (id == ("MessageStatusImg" + party))
status_img = node_tags[i];
}
}
avatar_img.id = "avatar:" + item.contact_info_str;
}
bubble_cell.id = item.id_str;
message_txt.id = "MessageText" + item.id_str;
name_tag.id = "MessageSenderName" + item.id_str;
business_img.id = "MessageBusinessCardImg" + item.id_str;
time_tag.id = "MessageTimeStamp" + item.id_str;
delivery_time_tag.id = "MessageDeliveryTimeStamp" + item.id_str;
status_img.id = "MessageStatusImg" + item.id_str;
message_txt.setAttribute("dir", item.text_dir);
/* Creation of an avatar image */
if (item.self == false) {
if (item.avatar != "") {
avatar_img.style.backgroundImage = "url('"+item.avatar+"')";
avatar_img.onclick = MessagingWidgetsRenderer_avatarClicked;
}
}
/* The bubble content */
bubble_cell.normalClassName = bubble_cell.className;
bubble_cell.clickedClassName = bubble_cell.className +
"Clicked MessagingBubbleClickedBackgroundColor MessagingBubbleBorderColor";
bubble_cell.onclick = MessagingWidgetsRenderer_messageClicked;
bubble_cell.onmousedown = MessagingWidgetsRenderer_messagePressBubble;
bubble_cell.onmouseup = MessagingWidgetsRenderer_messageReleaseBubble;
if (item.name_str != "") {
//name_tag.textContent = item.name_str;
name_tag.textContent = item.self? "<" : ">";
}
message_txt.innerHTML = item.message_str.replace(/\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
if (item.business_icon != "") {
business_img.src = item.business_icon;
}
time_tag.style.display = myShowTimes;
time_tag.textContent = fmtDate(item.time_str);
delivery_time_tag.style.display = myShowTimes;
delivery_time_tag.innerHTML = item.delivery_str;
if (item.status_icon != "") {
status_img.src = item.status_icon;
status_img.style.display = "inline";
} else {
/* Hiding element, so it's paddings etc don't affect timestamp */
/* placement. It gets hidden in SetTimes() also */
status_img.src = "";
status_img.style.display = "none";
}
/* FIXME: Move it somewhere appropriate */
MessagingWidgetsRenderer_fixPresence(item.self, presence_img, item.presence,
item.contact_info_str, add_to_top);
return new_message;
}
/**
* MessagingWidgetsRenderer_messageObject:
* @type: Type of the message (normal/action/notice/autoreply)
* @time_str: The time string to show in the screen
* @delivery_str: The delivery time string to possibly show in the screen
* @name_str: The name string to show in the screen
* @message_str: The actual message to show
* @self: TRUE if message is from self
* @id_str: The ID of the message for access
* @avatar: path(/url?) to avatar image
* @presence: presence icon of sender
* @business_icon: path to business card icon
* @status_icon: path to message status icon (pending/failed)
* @contact_info_str: Additional contact information
* @text_dir: Text direction ("ltr" or "rtl")
*
* Creates a message object.
**/
function
MessagingWidgetsRenderer_messageObject (
type, time_str, delivery_str, name_str, message_str, self, id_str,
avatar, presence, business_icon, status_icon, contact_info_str, text_dir)
{
this.type = type;
this.time_str = time_str;
this.delivery_str = delivery_str;
this.name_str = name_str;
this.message_str = message_str;
this.self = self;
this.id_str = id_str;
this.avatar = avatar;
this.presence = presence;
this.business_icon = business_icon;
this.status_icon = status_icon;
this.contact_info_str = contact_info_str;
this.text_dir = text_dir;
}
/*
* Flushes the given amount of messages from the buffer to renderer
*/
function
MessagingWidgetsRenderer_flushBuffer (amount)
{
if (messagesBuffer.length > 0) {
if (amount < 0)
amount = messagesBuffer.length;
var fragment = document.createDocumentFragment();
for (var i = 0; i < amount; i++) {
if (messagesBuffer.length <= 0)
break;
var item = messagesBuffer.shift();
new_message = MessagingWidgetsRenderer_messageNode (item, true);
if (fragment.childNodes.length > 0)
fragment.insertBefore(new_message, fragment.firstChild);
else
fragment.appendChild(new_message);
}
/* Restore scroll position */
var savedScrollPos =
document.body.scrollHeight - window.pageYOffset;
document.body.insertBefore(fragment, document.body.firstChild);
window.sizeToContent();
window.scrollTo(0, (document.body.scrollHeight - savedScrollPos));
}
}
/* Scroll event handler to potentially add more past history */
function
MessagingWidgetsRenderer_onScroll ()
{
MessagingWidgetsRenderer_clearHighlight();
/* Buffer flushing if there isn't already one running. */
if (window.pageYOffset < 100 && messagesBuffer.length > 0) {
/* Add a page of messages (about 4 screen-full) to renderer */
MessagingWidgetsRenderer_flushBuffer(HISTORY_PAGE_SIZE);
}
/* If we run out of messages in buffer and history hasn't finished,
* request for more
*/
if (messagesBuffer.length == 0 &&
myBatchRequested == HISTORY_FETCHING_NOREQUEST &&
myBatchesAdded > 0)
{
myBatchRequested = HISTORY_BATCH_SIZE;
alert("history-request:" + HISTORY_BATCH_SIZE);
}
obj=document.elementFromPoint(120, window.innerHeight-16);
if(obj.id != "")
storedBottomElement = obj;
}
/* When conversation view editor expands/shrinks, scroll accordingly to */
/* keep the the bottom position of the screen fixed. */
function
MessagingWidgetsRenderer_onResize (event)
{
if( storedScreenHeight != screen.height)
{
storedBottomElement.scrollIntoView(false);
storedScreenHeight = screen.height;
storedWindowHeight = window.innerHeight;
}
if (Math.abs(storedWindowHeight - window.innerHeight) != 0) {
window.scrollBy(0, storedWindowHeight - window.innerHeight);
storedWindowHeight = window.innerHeight;
}
}
/**
* MessagingWidgetsRenderer_addMessage:
* @type: Type of the message (normal/action/notice/autoreply)
* @time_str: The time string to show in the screen
* @delivery_str: The delivery time string to possibly show in the screen
* @name_str: The name string to show in the screen
* @message_str: The actual message to show
* @self: TRUE if message is from self
* @id_str: The ID of the message for access
* @avatar: path(/url?) to avatar image
* @presence: presence icon of sender
* @business_icon: path to business card icon
* @status_icon: path to message status icon (pending/failed)
* @contact_info_str: Additional contact information
* @add_to_top: Add the new message to the top of the list
* @text_dir: Text direction ("ltr" or "rtl")
*
* Queues messages to buffer and triggers flush schedule. Also forces
* an immediate flush if there are 8 messages already in buffer for
* the first time. It's a screenful of messages shown to the user in
* first opportunity.
**/
function
MessagingWidgetsRenderer_addMessage (
type, time_str, delivery_str, name_str, message_str, self, id_str,
avatar, presence, business_icon, status_icon, contact_info_str, add_to_top,
text_dir)
{
var item =
new MessagingWidgetsRenderer_messageObject (type, time_str,
delivery_str,
name_str, message_str,
self, id_str, avatar,
presence, business_icon,
status_icon,
contact_info_str,
text_dir);
if (add_to_top) {
/* Queue the top (history) message in buffer. */
messagesBuffer[messagesBuffer.length] = item;
/* Force flush if there's already screenful of messages to show for
* the first time.
*/
if (firstFlush == true &&
messagesBuffer.length >= HISTORY_SCREENFULL_SIZE)
{
firstFlush = false;
MessagingWidgetsRenderer_flushBuffer(HISTORY_SCREENFULL_SIZE);
}
} else {
/* If the message is bottom, add it directly without queuing. */
var new_message =
MessagingWidgetsRenderer_messageNode (item, false);
document.body.appendChild (new_message);
window.sizeToContent();
/* scrolling to new message, if the view is close to bottom, or */
/* sent by self. If not, we don't scroll */
if (document.body.scrollHeight - window.pageYOffset < (screen.height-140)*2 || self) {
new_message.scrollIntoView (false);
}
}
}
/**
* MessagingWidgetsRenderer_batchAdded:
* @messages_fetched: Number of messages fetched from log. Note that all
* fetched messages are not necessarily added to the view.
*
* History batch has been added to renderer
**/
function MessagingWidgetsRenderer_batchAdded (messages_fetched)
{
myBatchesAdded++;
/* Force flush if there hasn't been anything shown yet.
* This happens because the first batch was smaller than
* HISTORY_SCREENFULL_SIZE.
*/
if (firstFlush == true && messagesBuffer.length >= 0) {
firstFlush = false;
MessagingWidgetsRenderer_flushBuffer(-1);
}
/* If there was no request made, then it's the first batch pushed.
* The subsequent batch is requested after a delay of 1s to allow
* first screenfull to be rendered properly.
*/
if (myBatchRequested == HISTORY_FETCHING_NOREQUEST) {
if (flushTimeout != 0)
clearTimeout(flushTimeout);
flushTimeout = setTimeout("MessagingWidgetsRenderer_onScroll();",
1000);
} else if (myBatchRequested > 0) {
/* If there was a request, check if we got everything.
* If fetched messages is the amount requested, we could
* continue fetching more, otherwise there is no more history
* to fetch.
*/
if (messages_fetched < myBatchRequested) {
myBatchRequested = HISTORY_FETCHING_DONE; /* No more history */
} else {
myBatchRequested = HISTORY_FETCHING_NOREQUEST; /* Batch delivered */
}
/* Check if anything needs to be rendered at this scroll position */
MessagingWidgetsRenderer_onScroll();
}
}
/**
* MessagingWidgetsRenderer_deleteMessage:
*
* @id_str: The ID of the message to delete
*
* Removes a message from the message area
**/
function MessagingWidgetsRenderer_deleteMessage (id_str)
{
var txt;
var node = null;
MessagingWidgetsSMSConversation_alert(
"MessagingWidgetsRenderer_deleteMessage("+id_str+") called.");
txt = "Message"+id_str;
node = document.getElementById(txt);
if (node == null) {
MessagingWidgetsSMSConversation_alert (
"No messages with id: " + id_str);
return;
}
try {
document.body.removeChild (node);
window.scrollBy (0,0);
} catch (e) {
MessagingWidgetsSMSConversation_alert (
"Message " + index + " removal failed: " + e);
}
return;
}
/**
* MessagingWidgetsRenderer_showDeliveryTimes:
*
* @visibility: Set to 'inline' to show delivery time stamps. Set to
* 'none' not to show them.
*
* Set if delivery time stamps should be visible
**/
function MessagingWidgetsRenderer_showDeliveryTimes (visibility)
{
var times;
if (visibility != "inline" && visibility != "none") {
MessagingWidgetsSMSConversation_alert(
"MessagingWidgetsRenderer_showDeliveryTimes: Illegal parameter: " +
visibility);
return;
}
myShowTimes = visibility;
times = document.getElementsByTagName("span");
if (times == null) {
return;
}
for (i = 0; i < times.length; i++) {
if (times[i].className.indexOf ("MessageDeliveryTimeStamp") != -1) {
times[i].style.display = myShowTimes;
}
}
return;
}
/**
* MessagingWidgetsRenderer_setTimes:
*
* @id_str: id of the message
* @time_str: message time stamp
* @delivery_str: message delivery time stamp
* @status_icon: path+name of a status icon (pending/failed)
*
* Set time stamps and status icon
**/
function MessagingWidgetsRenderer_setTimes (id_str, time_str, delivery_str,
status_icon)
{
var icon;
// Weird new browser behaviour here. Looks like if the src of the status
// icon is set to not valid icon value, the browser keeps displaying the old
// valid icon. Only when you put to the src a valid icon does it change.
// Worked around this by hiding the image altogether if the icon is set
// to "".
icon = document.getElementById("MessageStatusImg"+id_str);
if (icon != null) {
icon.src = status_icon;
if (status_icon == "") {
icon.style.display = "none";
} else {
icon.style.display = "inline";
}
}
document.getElementById("MessageTimeStamp"+id_str).innerHTML = time_str;
document.getElementById("MessageDeliveryTimeStamp"+id_str).innerHTML =
delivery_str;
return;
}
/**
* MessagingWidgetsRenderer_setPresence:
* @contact_info: The contact info for presence icon
* @presence: Presence icon path
*
* Sets the presence icon of @contact_info to @presence
**/
function MessagingWidgetsRenderer_setPresence (contact_info, presence)
{
var presenceImg = document.getElementById ("PresenceImg" + contact_info);
if (presenceImg != null) {
presenceImg.src = presence;
} else {
/* Find in buffer */
for (var i = 0; i < messagesBuffer.length; i++) {
if (messagesBuffer[i].contact_info_str == contact_info) {
messagesBuffer[i].presence = presence;
break;
}
}
}
}
/**
* MessagingWidgetsRenderer_setMaxMessages:
*
* @max: maximum number of messages
*
* Sets the maximum number of messages (default is 50)
**/
function MessagingWidgetsRenderer_setMaxMessages (max)
{
var count;
myMaxMessages = max;
count = document.body.childNodes.count;
if (count >= myMaxMessages) {
var i;
for (i = count - myMaxMessages + 1; i > 0; i--) {
document.body.removeChild (document.body.firstChild);
}
}
return;
}
/**
* MessagingWidgetsRenderer_setCSS:
*
* @file: Path of theme CSS file
*
* Sets the theme CSS file to the current page.
*
* FIXME: Should use the .styleSheets property of the document
**/
function MessagingWidgetsRenderer_setCSS (file)
{
// document.getElementById("ThemeCSSLink").href = file;
MessagingWidgetsSMSConversation_alert("set: "+file+" as theme CSS file.");
return;
}
/**
* MessagingWidgetsRenderer_addBatch:
*
* @messages: Array of messages to add
*
* Adds several messages to view
*
**/
function MessagingWidgetsRenderer_addBatch (messages)
{
var len = messages.length;
var i;
// starting from 1, because of the extra ',' at the beginning due to
// performance optimizations
for(i=1; i<len; i++) {
// Calling addMessage for each batched call. Converting strings
// representing bool/int parameters
MessagingWidgetsRenderer_addMessage(Number(messages[i][0]),
messages[i][1], messages[i][2], messages[i][3], messages[i][4],
(messages[i][5] === 'true'), messages[i][6], messages[i][7],
messages[i][8], messages[i][9], messages[i][10], messages[i][11],
(messages[i][12]) === 'true', messages[i][13]);
}
return;
}
/**
* @file MessagingWidgetsSMSConversation.js
*
* Javascript for messaging rendering widget's ring buffer.
*/
/*
* This file is part of rtcom messaging ui
*
* Copyright (C) 2009 Nokia Corporation. All rights reserved.
*
* Contact: Naba Kumar <naba.kumar@nokia.com>
*
* This software, including documentation, is protected by copyright
* controlled by Nokia Corporation. All rights are reserved.
* Copying, including reproducing, storing, adapting or translating,
* any or all of this material requires the prior written consent of
* Nokia Corporation. This material also contains confidential
* information which may not be disclosed to others without the prior
* written consent of Nokia.
*/
/**
* Globals:
*
* @myBatchRequested:
* if HISTORY_FETCHING_NOREQUEST, no batch has been requested.
* if HISTORY_FETCHING_DONE, history fetching done; no more request to give.
* if > 0, request in progress and the amount requested.
*
* @myBatchesAdded: Number of message batches retrieved from log.
*
* @myShowTimes: Display method for time stamps, set to 'inline' to show
* and 'none' to hide
*
**/
var HISTORY_BATCH_SIZE = 30;
var HISTORY_PAGE_SIZE = 15;
var HISTORY_SCREENFULL_SIZE = 8;
var HISTORY_FETCHING_DONE = -1;
var HISTORY_FETCHING_NOREQUEST = 0;
var myBatchRequested = 0;
var myShowTimes = "inline";
var myBatchesAdded = 0;
var myMaxMessages = -1;
var markupTemplateSelf;
var markupTemplateOther;
var messagesBuffer = new Array();
var pastPresenceAnchor = new Array();
var firstFlush = true;
var flushTimeout = 0;
var lastClickedBubble = null;
var storedWindowHeight = 340;
/**
* MessagingWidgetsSMSConversation_alert:
* @str Parameter to set for alert() call
*
* Custom, error safe alert call. Apparently with some version mismatches, the
* alert() javascript function sometimes fails. This is to prevent alert()
* failure to prevent rest of the script execution.
*
* For functionality, that actually depends on alert() call to succeed this
* is not helpful, rather it's another way of creating a malfuction that is
* harder to detect.
**/
function MessagingWidgetsSMSConversation_alert(str)
{
alert(str);
}
/**
* MessagingWidgetsSMSConversation_init:
*
* Called when the page has actually been loaded.
* Acts as a "constructor", could be used for creating the template item and
* getting the element where we will add the children in the page.
*
* However, creating such template items doesn't seem so simple, we would
* need several of them in order to be able to keep it really usable.
**/
function MessagingWidgetsSMSConversation_init ()
{
/* Setting onscroll handler to window */
window.onscroll = MessagingWidgetsRenderer_onScroll;
/* Setting onresize handler to window */
window.onresize = MessagingWidgetsRenderer_onResize;
/* setting body onmousedown for clearing stored message id on ui side */
document.body.onmousedown = MessagingWidgetsRenderer_messagePressBody;
if (!markupTemplateSelf)
{
markupTemplateSelf = document.getElementById("MessageContainerSelf");
markupTemplateSelf.parentNode.removeChild(markupTemplateSelf);
markupTemplateSelf.removeAttribute('id');
markupTemplateOther = document.getElementById("MessageContainerOther");
markupTemplateOther.parentNode.removeChild(markupTemplateOther);
markupTemplateOther.removeAttribute('id');
}
}
/**
* MessagingWidgetsRenderer_messageClicked:
* @event:
* @id:
*
* Message area clicked
**/
function MessagingWidgetsRenderer_messageClicked (event)
{
var x = event.target;
var idstr;
/* Only handle clicks on message blocks, not on URIs */
if (x.href == "" || (!x.href && !x.parentNode.href)){
}else{
return true;
}
idstr = "file://id:"+event.currentTarget.id;
MessagingWidgetsSMSConversation_alert(idstr);
MessagingWidgetsRenderer_clearHighlight(event.currentTarget.id);
event.returnValue = true;
event.cancelBubble = false;
}
function MessagingWidgetsRenderer_messagePress (event)
{
var idstr;
idstr = "file://pre-id:"+event.currentTarget.id;
MessagingWidgetsSMSConversation_alert(idstr);
/* The popup menu posted from C code seems to steal events
and when the popup is closed, the message remains highlighted.
Workaround: use a 2-second timeout to clear highlight.
*/
setTimeout("MessagingWidgetsRenderer_clearHighlight()", 2000);
event.returnValue = true;
/* Canceling bubble so body onmousedown isn't called */
event.cancelBubble = true;
}
/**
* MessagingWidgetsRenderer_messagePressBubble:
* @event: An onmousedown event
* Highlight message bubble when pressed.
*/
function MessagingWidgetsRenderer_messagePressBubble (event)
{
var block;
MessagingWidgetsRenderer_clearHighlight(event.currentTarget.id);
block = document.getElementById(event.currentTarget.id);
if (block) {
block.className = block.clickedClassName;
lastClickedBubble = block;
}
event.returnValue = true;
/* Canceling bubble so body onmousedown isn't called */
event.cancelBubble = false;
}
/**
* MessagingWidgetsRenderer_messagePressBubble:
* @event: (Usually) an onmouseup event
* Message bubble is not pressed any more - clear highlighting.
*/
function MessagingWidgetsRenderer_messageReleaseBubble (event)
{
MessagingWidgetsRenderer_clearHighlight();
event.returnValue = true;
event.cancelBubble = false;
}
/**
* MessagingWidgetsRenderer_clearHighlight:
* @elem_id: (optional) Don't clear if @elem_id is currently highlighted.
*
* Remove highlighting from highlighted element, if any.
*/
function MessagingWidgetsRenderer_clearHighlight (/* [elem_id] */)
{
if (lastClickedBubble) {
if (arguments.length >= 0) {
var elem_id = arguments[0];
var elem = document.getElementById(elem_id);
if (elem && elem == lastClickedBubble) {
return;
}
}
lastClickedBubble.className = lastClickedBubble.normalClassName;
lastClickedBubble = null;
}
}
function MessagingWidgetsRenderer_messagePressBody (event)
{
var idstr;
MessagingWidgetsSMSConversation_alert("file://pre-id:None");
event.returnValue = true;
event.cancelBubble = false;
}
function MessagingWidgetsRenderer_avatarClicked (event)
{
MessagingWidgetsSMSConversation_alert(event.currentTarget.id);
event.returnValue = true;
event.cancelBubble = false;
}
/*
* Fixes presence...
*/
function
MessagingWidgetsRenderer_fixPresence (
self, presence_img, presence, contact_info_str, add_to_top)
{
var presenceID = "PresenceImg" + contact_info_str;
if (!self) {
if (presence_img) {
presence_img.id = presenceID;
if (presence != null && presence != "") {
presence_img.src = presence;
}
/* Find current presence anchor in document */
var prevPresence = document.getElementById (presenceID);
if (add_to_top) {
/* If we are adding a history, check if presence anchor is
* already present in document (presumably added at bottom
* from pending messages) or in pastPresenceAnchor which
* remebers if we already created the anchor (it should
* not be re-created if already created when populating
* history).
*/
if (prevPresence ||
pastPresenceAnchor[contact_info_str] == true) {
/*
* Presence is already anchored; remove it from this item.
*/
presence_img.parentNode.removeChild (presence_img);
} else{
/*
* There is no anchor found, either in document or in
* previously anchored, so leave presence node intact
* in this item and record that anchor is already set.
*/
pastPresenceAnchor[contact_info_str] = true;
}
} else {
/* If we found a previous presence icon, we remove that.
* this one replaces the anchor
*/
if (prevPresence) {
prevPresence.parentNode.removeChild (prevPresence);
}
}
}
} else if (presence_img) {
presence_img.parentNode.removeChild (presence_img);
}
}
/**
* MessagingWidgetsRenderer_messageNode:
* @item: The message.
* @add_to_top: Add the new message to the top of the list
*
* Creates a message node
**/
function
MessagingWidgetsRenderer_messageNode (item, add_to_top)
{
/* Top level items */
var new_message;
/* Avatar data */
var avatar_img;
/* The graphics */
var bubble_cell;
/* Presence icon and name area */
var presence_img = null;
var name_tag;
/* Message text content */
var message_txt;
/* Time stamps and potential icons */
var time_tag;
var delivery_time_tag;
var business_img;
var status_img;
var party;
var count;
if (!markupTemplateSelf) {
MessagingWidgetsSMSConversation_init();
}
if (item.type != 0) {
MessagingWidgetsSMSConversation_alert("Only type 0 is allowed");
return;
}
if (item.self == true) {
party = "Self";
new_message = markupTemplateSelf.cloneNode(true);
/* Finally, append the whole message to the document */
new_message.id = "Message" + item.id_str;
new_message.onmousedown = MessagingWidgetsRenderer_messagePress;
/* Retrieve the elements to update */
var node_tags = new_message.getElementsByTagName('*');
for (var i = 0; i < node_tags.length; i++) {
if (node_tags[i].hasAttribute('id')) {
var id = node_tags[i].getAttribute('id');
if (id == ("AvatarImg" + party))
avatar_img = node_tags[i];
if (id == ("Message" + party))
bubble_cell = node_tags[i];
if (id == ("MessagePresence" + party))
presence_img = node_tags[i];
if (id == ("MessageSenderName" + party))
name_tag = node_tags[i];
if (id == ("MessageText" + party))
message_txt = node_tags[i];
if (id == ("MessageTimeStamp" + party))
time_tag = node_tags[i];
if (id == ("MessageBusinessCardImg" + party))
business_img = node_tags[i];
if (id == ("MessageDeliveryTimeStamp" + party))
delivery_time_tag = node_tags[i];
if (id == ("MessageStatusImg" + party))
status_img = node_tags[i];
}
}
} else {
party = "Other";
new_message = markupTemplateOther.cloneNode(true);
/* Finally, append the whole message to the document */
new_message.id = "Message" + item.id_str;
new_message.onmousedown = MessagingWidgetsRenderer_messagePress;
/* Retrieve the elements to update */
var node_tags = new_message.getElementsByTagName('*');
for (var i = 0; i < node_tags.length; i++) {
if (node_tags[i].hasAttribute('id')) {
var id = node_tags[i].getAttribute('id');
if (id == ("AvatarImg" + party))
avatar_img = node_tags[i];
if (id == ("Message" + party))
bubble_cell = node_tags[i];
if (id == ("MessagePresence" + party))
presence_img = node_tags[i];
if (id == ("MessageSenderName" + party))
name_tag = node_tags[i];
if (id == ("MessageText" + party))
message_txt = node_tags[i];
if (id == ("MessageTimeStamp" + party))
time_tag = node_tags[i];
if (id == ("MessageBusinessCardImg" + party))
business_img = node_tags[i];
if (id == ("MessageDeliveryTimeStamp" + party))
delivery_time_tag = node_tags[i];
if (id == ("MessageStatusImg" + party))
status_img = node_tags[i];
}
}
avatar_img.id = "avatar:" + item.contact_info_str;
}
bubble_cell.id = item.id_str;
message_txt.id = "MessageText" + item.id_str;
name_tag.id = "MessageSenderName" + item.id_str;
business_img.id = "MessageBusinessCardImg" + item.id_str;
time_tag.id = "MessageTimeStamp" + item.id_str;
delivery_time_tag.id = "MessageDeliveryTimeStamp" + item.id_str;
status_img.id = "MessageStatusImg" + item.id_str;
message_txt.setAttribute("dir", item.text_dir);
/* Creation of an avatar image */
if (item.self == false) {
if (item.avatar != "") {
avatar_img.style.backgroundImage = "url('"+item.avatar+"')";
avatar_img.onclick = MessagingWidgetsRenderer_avatarClicked;
}
}
/* The bubble content */
bubble_cell.normalClassName = bubble_cell.className;
bubble_cell.clickedClassName = bubble_cell.className +
"Clicked MessagingBubbleClickedBackgroundColor MessagingBubbleBorderColor";
bubble_cell.onclick = MessagingWidgetsRenderer_messageClicked;
bubble_cell.onmousedown = MessagingWidgetsRenderer_messagePressBubble;
bubble_cell.onmouseup = MessagingWidgetsRenderer_messageReleaseBubble;
if (item.name_str != "") {
name_tag.textContent = item.name_str;
}
message_txt.innerHTML = item.message_str.replace(/\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
if (item.business_icon != "") {
business_img.src = item.business_icon;
}
time_tag.style.display = myShowTimes;
time_tag.innerHTML = item.time_str;
delivery_time_tag.style.display = myShowTimes;
delivery_time_tag.innerHTML = item.delivery_str;
if (item.status_icon != "") {
status_img.src = item.status_icon;
status_img.style.display = "inline";
} else {
/* Hiding element, so it's paddings etc don't affect timestamp */
/* placement. It gets hidden in SetTimes() also */
status_img.src = "";
status_img.style.display = "none";
}
/* FIXME: Move it somewhere appropriate */
MessagingWidgetsRenderer_fixPresence(item.self, presence_img, item.presence,
item.contact_info_str, add_to_top);
return new_message;
}
/**
* MessagingWidgetsRenderer_messageObject:
* @type: Type of the message (normal/action/notice/autoreply)
* @time_str: The time string to show in the screen
* @delivery_str: The delivery time string to possibly show in the screen
* @name_str: The name string to show in the screen
* @message_str: The actual message to show
* @self: TRUE if message is from self
* @id_str: The ID of the message for access
* @avatar: path(/url?) to avatar image
* @presence: presence icon of sender
* @business_icon: path to business card icon
* @status_icon: path to message status icon (pending/failed)
* @contact_info_str: Additional contact information
* @text_dir: Text direction ("ltr" or "rtl")
*
* Creates a message object.
**/
function
MessagingWidgetsRenderer_messageObject (
type, time_str, delivery_str, name_str, message_str, self, id_str,
avatar, presence, business_icon, status_icon, contact_info_str, text_dir)
{
this.type = type;
this.time_str = time_str;
this.delivery_str = delivery_str;
this.name_str = name_str;
this.message_str = message_str;
this.self = self;
this.id_str = id_str;
this.avatar = avatar;
this.presence = presence;
this.business_icon = business_icon;
this.status_icon = status_icon;
this.contact_info_str = contact_info_str;
this.text_dir = text_dir;
}
/*
* Flushes the given amount of messages from the buffer to renderer
*/
function
MessagingWidgetsRenderer_flushBuffer (amount)
{
if (messagesBuffer.length > 0) {
if (amount < 0)
amount = messagesBuffer.length;
var fragment = document.createDocumentFragment();
for (var i = 0; i < amount; i++) {
if (messagesBuffer.length <= 0)
break;
var item = messagesBuffer.shift();
new_message = MessagingWidgetsRenderer_messageNode (item, true);
if (fragment.childNodes.length > 0)
fragment.insertBefore(new_message, fragment.firstChild);
else
fragment.appendChild(new_message);
}
/* Restore scroll position */
var savedScrollPos =
document.body.scrollHeight - window.pageYOffset;
document.body.insertBefore(fragment, document.body.firstChild);
window.sizeToContent();
window.scrollTo(0, (document.body.scrollHeight - savedScrollPos));
}
}
/* Scroll event handler to potentially add more past history */
function
MessagingWidgetsRenderer_onScroll ()
{
MessagingWidgetsRenderer_clearHighlight();
/* Buffer flushing if there isn't already one running. */
if (window.pageYOffset < 100 && messagesBuffer.length > 0) {
/* Add a page of messages (about 4 screen-full) to renderer */
MessagingWidgetsRenderer_flushBuffer(HISTORY_PAGE_SIZE);
}
/* If we run out of messages in buffer and history hasn't finished,
* request for more
*/
if (messagesBuffer.length == 0 &&
myBatchRequested == HISTORY_FETCHING_NOREQUEST &&
myBatchesAdded > 0)
{
myBatchRequested = HISTORY_BATCH_SIZE;
alert("history-request:" + HISTORY_BATCH_SIZE);
}
}
/* When conversation view editor expands/shrinks, scroll accordingly to */
/* keep the the bottom position of the screen fixed. */
function
MessagingWidgetsRenderer_onResize (event)
{
if (Math.abs(storedWindowHeight - window.innerHeight) != 0) {
window.scrollBy(0, storedWindowHeight - window.innerHeight);
storedWindowHeight = window.innerHeight;
}
}
/**
* MessagingWidgetsRenderer_addMessage:
* @type: Type of the message (normal/action/notice/autoreply)
* @time_str: The time string to show in the screen
* @delivery_str: The delivery time string to possibly show in the screen
* @name_str: The name string to show in the screen
* @message_str: The actual message to show
* @self: TRUE if message is from self
* @id_str: The ID of the message for access
* @avatar: path(/url?) to avatar image
* @presence: presence icon of sender
* @business_icon: path to business card icon
* @status_icon: path to message status icon (pending/failed)
* @contact_info_str: Additional contact information
* @add_to_top: Add the new message to the top of the list
* @text_dir: Text direction ("ltr" or "rtl")
*
* Queues messages to buffer and triggers flush schedule. Also forces
* an immediate flush if there are 8 messages already in buffer for
* the first time. It's a screenful of messages shown to the user in
* first opportunity.
**/
function
MessagingWidgetsRenderer_addMessage (
type, time_str, delivery_str, name_str, message_str, self, id_str,
avatar, presence, business_icon, status_icon, contact_info_str, add_to_top,
text_dir)
{
var item =
new MessagingWidgetsRenderer_messageObject (type, time_str,
delivery_str,
name_str, message_str,
self, id_str, avatar,
presence, business_icon,
status_icon,
contact_info_str,
text_dir);
if (add_to_top) {
/* Queue the top (history) message in buffer. */
messagesBuffer[messagesBuffer.length] = item;
/* Force flush if there's already screenful of messages to show for
* the first time.
*/
if (firstFlush == true &&
messagesBuffer.length >= HISTORY_SCREENFULL_SIZE)
{
firstFlush = false;
MessagingWidgetsRenderer_flushBuffer(HISTORY_SCREENFULL_SIZE);
}
} else {
/* If the message is bottom, add it directly without queuing. */
var new_message =
MessagingWidgetsRenderer_messageNode (item, false);
document.body.appendChild (new_message);
window.sizeToContent();
/* scrolling to new message, if the view is close to bottom, or */
/* sent by self. If not, we don't scroll */
if (document.body.scrollHeight - window.pageYOffset < 640 || self) {
new_message.scrollIntoView (false);
}
}
}
/**
* MessagingWidgetsRenderer_batchAdded:
* @messages_fetched: Number of messages fetched from log. Note that all
* fetched messages are not necessarily added to the view.
*
* History batch has been added to renderer
**/
function MessagingWidgetsRenderer_batchAdded (messages_fetched)
{
myBatchesAdded++;
/* Force flush if there hasn't been anything shown yet.
* This happens because the first batch was smaller than
* HISTORY_SCREENFULL_SIZE.
*/
if (firstFlush == true && messagesBuffer.length >= 0) {
firstFlush = false;
MessagingWidgetsRenderer_flushBuffer(-1);
}
/* If there was no request made, then it's the first batch pushed.
* The subsequent batch is requested after a delay of 1s to allow
* first screenfull to be rendered properly.
*/
if (myBatchRequested == HISTORY_FETCHING_NOREQUEST) {
if (flushTimeout != 0)
clearTimeout(flushTimeout);
flushTimeout = setTimeout("MessagingWidgetsRenderer_onScroll();",
1000);
} else if (myBatchRequested > 0) {
/* If there was a request, check if we got everything.
* If fetched messages is the amount requested, we could
* continue fetching more, otherwise there is no more history
* to fetch.
*/
if (messages_fetched < myBatchRequested) {
myBatchRequested = HISTORY_FETCHING_DONE; /* No more history */
} else {
myBatchRequested = HISTORY_FETCHING_NOREQUEST; /* Batch delivered */
}
/* Check if anything needs to be rendered at this scroll position */
MessagingWidgetsRenderer_onScroll();
}
}
/**
* MessagingWidgetsRenderer_deleteMessage:
*
* @id_str: The ID of the message to delete
*
* Removes a message from the message area
**/
function MessagingWidgetsRenderer_deleteMessage (id_str)
{
var txt;
var node = null;
MessagingWidgetsSMSConversation_alert(
"MessagingWidgetsRenderer_deleteMessage("+id_str+") called.");
txt = "Message"+id_str;
node = document.getElementById(txt);
if (node == null) {
MessagingWidgetsSMSConversation_alert (
"No messages with id: " + id_str);
return;
}
try {
document.body.removeChild (node);
window.scrollBy (0,0);
} catch (e) {
MessagingWidgetsSMSConversation_alert (
"Message " + index + " removal failed: " + e);
}
return;
}
/**
* MessagingWidgetsRenderer_showDeliveryTimes:
*
* @visibility: Set to 'inline' to show delivery time stamps. Set to
* 'none' not to show them.
*
* Set if delivery time stamps should be visible
**/
function MessagingWidgetsRenderer_showDeliveryTimes (visibility)
{
var times;
if (visibility != "inline" && visibility != "none") {
MessagingWidgetsSMSConversation_alert(
"MessagingWidgetsRenderer_showDeliveryTimes: Illegal parameter: " +
visibility);
return;
}
myShowTimes = visibility;
times = document.getElementsByTagName("span");
if (times == null) {
return;
}
for (i = 0; i < times.length; i++) {
if (times[i].className.indexOf ("MessageDeliveryTimeStamp") != -1) {
times[i].style.display = myShowTimes;
}
}
return;
}
/**
* MessagingWidgetsRenderer_setTimes:
*
* @id_str: id of the message
* @time_str: message time stamp
* @delivery_str: message delivery time stamp
* @status_icon: path+name of a status icon (pending/failed)
*
* Set time stamps and status icon
**/
function MessagingWidgetsRenderer_setTimes (id_str, time_str, delivery_str,
status_icon)
{
var icon;
// Weird new browser behaviour here. Looks like if the src of the status
// icon is set to not valid icon value, the browser keeps displaying the old
// valid icon. Only when you put to the src a valid icon does it change.
// Worked around this by hiding the image altogether if the icon is set
// to "".
icon = document.getElementById("MessageStatusImg"+id_str);
if (icon != null) {
icon.src = status_icon;
if (status_icon == "") {
icon.style.display = "none";
} else {
icon.style.display = "inline";
}
}
document.getElementById("MessageTimeStamp"+id_str).innerHTML = time_str;
document.getElementById("MessageDeliveryTimeStamp"+id_str).innerHTML =
delivery_str;
return;
}
/**
* MessagingWidgetsRenderer_setPresence:
* @contact_info: The contact info for presence icon
* @presence: Presence icon path
*
* Sets the presence icon of @contact_info to @presence
**/
function MessagingWidgetsRenderer_setPresence (contact_info, presence)
{
var presenceImg = document.getElementById ("PresenceImg" + contact_info);
if (presenceImg != null) {
presenceImg.src = presence;
} else {
/* Find in buffer */
for (var i = 0; i < messagesBuffer.length; i++) {
if (messagesBuffer[i].contact_info_str == contact_info) {
messagesBuffer[i].presence = presence;
break;
}
}
}
}
/**
* MessagingWidgetsRenderer_setMaxMessages:
*
* @max: maximum number of messages
*
* Sets the maximum number of messages (default is 50)
**/
function MessagingWidgetsRenderer_setMaxMessages (max)
{
var count;
myMaxMessages = max;
count = document.body.childNodes.count;
if (count >= myMaxMessages) {
var i;
for (i = count - myMaxMessages + 1; i > 0; i--) {
document.body.removeChild (document.body.firstChild);
}
}
return;
}
/**
* MessagingWidgetsRenderer_setCSS:
*
* @file: Path of theme CSS file
*
* Sets the theme CSS file to the current page.
*
* FIXME: Should use the .styleSheets property of the document
**/
function MessagingWidgetsRenderer_setCSS (file)
{
document.getElementById("ThemeCSSLink").href = file;
MessagingWidgetsSMSConversation_alert("set: "+file+" as theme CSS file.");
return;
}
/**
* MessagingWidgetsRenderer_addBatch:
*
* @messages: Array of messages to add
*
* Adds several messages to view
*
**/
function MessagingWidgetsRenderer_addBatch (messages)
{
var len = messages.length;
var i;
// starting from 1, because of the extra ',' at the beginning due to
// performance optimizations
for(i=1; i<len; i++) {
// Calling addMessage for each batched call. Converting strings
// representing bool/int parameters
MessagingWidgetsRenderer_addMessage(Number(messages[i][0]),
messages[i][1], messages[i][2], messages[i][3], messages[i][4],
(messages[i][5] === 'true'), messages[i][6], messages[i][7],
messages[i][8], messages[i][9], messages[i][10], messages[i][11],
(messages[i][12]) === 'true', messages[i][13]);
}
return;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment