Last active
June 1, 2018 09:18
-
-
Save Maxdamantus/745b8ffb36adef889e5aa94b0f6ac49b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @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, " "); | |
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; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @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, " "); | |
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; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @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 | |
*/ | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @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, " "); | |
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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @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, " "); | |
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; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @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, " "); | |
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