1 /* JavaScript for SOGoMail */
5 if (typeof textMailAccounts != 'undefined')
6 mailAccounts = textMailAccounts.evalJSON(true);
8 var currentMessages = new Array();
9 var maxCachedMessages = 20;
10 var cachedMessages = new Array();
11 var currentMailbox = null;
12 var currentMailboxType = "";
14 var usersRightsWindowHeight = 320;
15 var usersRightsWindowWidth = 400;
19 var deleteMessageRequestCount = 0;
21 var messageCheckTimer;
25 function openMessageWindow(msguid, url) {
28 wId += "SOGo_msg_" + msguid;
29 markMailReadInWindow(window, msguid);
31 var msgWin = openMailComposeWindow(url, wId);
37 function onMessageDoubleClick(event) {
40 if (currentMailboxType == "draft")
45 return openMessageWindowsForSelection(action, true);
48 function toggleMailSelect(sender) {
51 row.className = sender.checked ? "tableview_selected" : "tableview";
54 function openAddressbook(sender) {
57 urlstr = ApplicationBaseURL + "/../Contacts/?popup=YES";
58 var w = window.open(urlstr, "Addressbook",
59 "width=640,height=400,resizable=1,scrollbars=1,toolbar=0,"
60 + "location=no,directories=0,status=0,menubar=0,copyhistory=0");
66 function onMenuSharing(event) {
67 var folderID = document.menuTarget.getAttribute("dataname");
68 var type = document.menuTarget.getAttribute("datatype");
70 if (type == "additional")
71 window.alert(clabels["The user rights cannot be"
72 + " edited for this object!"]);
74 var urlstr = URLForFolderID(folderID) + "/acls";
75 openAclWindow(urlstr);
79 /* mail list DOM changes */
81 function markMailInWindow(win, msguid, markread) {
84 msgDiv = win.$("div_" + msguid);
87 msgDiv.removeClassName("mailer_unreadmailsubject");
88 msgDiv.addClassName("mailer_readmailsubject");
89 msgDiv = win.$("unreaddiv_" + msguid);
92 msgDiv.setAttribute("class", "mailerUnreadIcon");
93 msgDiv.setAttribute("id", "readdiv_" + msguid);
94 msgDiv.setAttribute("src", ResourcesURL + "/icon_read.gif");
95 msgDiv.setAttribute("onclick", "mailListMarkMessage(this,"
96 + " 'markMessageUnread', " + msguid
99 var title = msgDiv.getAttribute("title-markunread");
101 msgDiv.setAttribute("title", title);
105 msgDiv.removeClassName('mailer_readmailsubject');
106 msgDiv.addClassName('mailer_unreadmailsubject');
107 msgDiv = win.$("readdiv_" + msguid);
110 msgDiv.setAttribute("class", "mailerReadIcon");
111 msgDiv.setAttribute("id", "unreaddiv_" + msguid);
112 msgDiv.setAttribute("src", ResourcesURL + "/icon_unread.gif");
113 msgDiv.setAttribute("onclick", "mailListMarkMessage(this,"
114 + " 'markMessageRead', " + msguid
117 var title = msgDiv.getAttribute("title-markread");
119 msgDiv.setAttribute("title", title);
128 function markMailReadInWindow(win, msguid) {
129 /* this is called by UIxMailView with window.opener */
130 return markMailInWindow(win, msguid, true);
133 /* mail list reply */
135 function openMessageWindowsForSelection(action, firstOnly) {
136 if (document.body.hasClassName("popup")) {
140 var messageList = $("messageList");
141 var rows = messageList.getSelectedRowsId();
142 if (rows.length > 0) {
143 for (var i = 0; i < rows.length; i++) {
144 openMessageWindow(rows[i].substr(4),
145 ApplicationBaseURL + currentMailbox
146 + "/" + rows[i].substr(4)
152 window.alert(labels["Please select a message."]);
159 function mailListMarkMessage(event) {
160 var http = createHTTPClient();
161 var url = ApplicationBaseURL + currentMailbox + "/" + msguid + "/" + action;
164 // TODO: add parameter to signal that we are only interested in OK
165 http.open("POST", url, false /* not async */);
167 if (http.status != 200) {
168 // TODO: refresh page?
169 alert("Message Mark Failed: " + http.statusText);
170 window.location.reload();
173 markMailInWindow(window, msguid, markread);
177 window.location.href = url;
181 /* maillist row highlight */
183 var oldMaillistHighlight = null; // to remember deleted/selected style
185 function ml_highlight(sender) {
186 oldMaillistHighlight = sender.className;
187 if (oldMaillistHighlight == "tableview_highlight")
188 oldMaillistHighlight = null;
189 sender.className = "tableview_highlight";
192 function ml_lowlight(sender) {
193 if (oldMaillistHighlight) {
194 sender.className = oldMaillistHighlight;
195 oldMaillistHighlight = null;
198 sender.className = "tableview";
202 /* bulk delete of messages */
204 function deleteSelectedMessages(sender) {
205 var messageList = $("messageList");
206 var rowIds = messageList.getSelectedRowsId();
208 for (var i = 0; i < rowIds.length; i++) {
210 var rowId = rowIds[i].substr(4);
211 var messageId = currentMailbox + "/" + rowId;
212 url = ApplicationBaseURL + messageId + "/trash";
213 deleteMessageRequestCount++;
214 var data = { "id": rowId, "mailbox": currentMailbox, "messageId": messageId };
215 triggerAjaxRequest(url, deleteSelectedMessagesCallback, data);
221 function deleteSelectedMessagesCallback(http) {
222 if (http.readyState == 4) {
223 if (isHttpStatus204(http.status)) {
224 var data = http.callbackData;
225 deleteCachedMessage(data["messageId"]);
226 if (currentMailbox == data["mailbox"]) {
228 var div = $('messageContent');
229 if (currentMessages[currentMailbox] == data["id"]) {
231 currentMessages[currentMailbox] = null;
234 var row = $("row_" + data["id"]);
235 row.parentNode.removeChild(row);
236 // row.addClassName("deleted"); // when we'll offer "mark as deleted"
238 deleteMessageRequestCount--;
243 log ("deleteSelectedMessagesCallback: problem during ajax request " + http.status);
246 function deleteDraft(url) {
247 /* this is called by UIxMailEditor with window.opener */
248 new Ajax.Request(url, {
250 onFailure: function(transport) {
251 if (!isHttpStatus204)
252 log("draftDeleteCallback: problem during ajax request: " + transport.status);
257 function moveMessages(rowIds, folder) {
260 for (var i = 0; i < rowIds.length; i++) {
263 /* send AJAX request (synchronously) */
265 var messageId = currentMailbox + "/" + rowIds[i];
266 url = (ApplicationBaseURL + messageId
267 + "/move?tofolder=" + folder);
268 http = createHTTPClient();
269 http.open("GET", url, false /* not async */);
271 if (http.status == 200) {
272 var row = $("row_" + rowIds[i]);
273 row.parentNode.removeChild(row);
274 deleteCachedMessage(messageId);
275 if (currentMessages[currentMailbox] == rowIds[i]) {
276 var div = $('messageContent');
278 currentMessages[currentMailbox] = null;
281 else /* request failed */
284 /* remove from page */
286 /* line-through would be nicer, but hiding is OK too */
290 alert("Could not move " + failCount + " messages!");
295 function onMenuDeleteMessage(event) {
296 deleteSelectedMessages();
297 preventDefault(event);
300 function onPrintCurrentMessage(event) {
301 var rowIds = $("messageList").getSelectedRowsId();
302 if (rowIds.length == 0) {
303 window.alert(labels["Please select a message to print."]);
305 else if (rowIds.length > 1) {
306 window.alert(labels["Please select only one message to print."]);
311 preventDefault(event);
314 function onMailboxTreeItemClick(event) {
315 var topNode = $("mailboxTree");
316 var mailbox = this.parentNode.getAttribute("dataname");
318 if (topNode.selectedEntry)
319 topNode.selectedEntry.deselect();
321 topNode.selectedEntry = this;
325 $("searchValue").value = "";
328 currentMailboxType = this.parentNode.getAttribute("datatype");
329 if (currentMailboxType == "account" || currentMailboxType == "additional") {
330 currentMailbox = mailbox;
331 $("messageContent").update();
332 var table = $("messageList");
333 var head = table.tHead;
334 var body = table.tBodies[0];
335 for (var i = body.rows.length; i > 0; i--)
338 head.rows[1].firstChild.update();
341 openMailbox(mailbox);
346 function _onMailboxMenuAction(menuEntry, error, actionName) {
347 var targetMailbox = menuEntry.mailbox.fullName();
349 if (targetMailbox == currentMailbox)
350 window.alert(labels[error]);
353 if (document.menuTarget.tagName == "DIV")
354 message = currentMessages[currentMailbox];
356 message = document.menuTarget.getAttribute("id").substr(4);
358 var urlstr = (URLForFolderID(currentMailbox) + "/" + message
359 + "/" + actionName + "?folder=" + targetMailbox);
360 triggerAjaxRequest(urlstr, folderRefreshCallback, currentMailbox);
364 function onMailboxMenuMove(event) {
365 _onMailboxMenuAction(this,
366 "Moving a message into its own folder is impossible!",
370 function onMailboxMenuCopy(event) {
371 _onMailboxMenuAction(this,
372 "Copying a message into its own folder is impossible!",
376 function refreshMailbox() {
377 var topWindow = getTopWindow();
379 topWindow.refreshCurrentFolder();
384 function onComposeMessage() {
385 var topWindow = getTopWindow();
387 topWindow.composeNewMessage();
392 function composeNewMessage() {
393 var account = currentMailbox.split("/")[1];
394 var url = ApplicationBaseURL + "/" + account + "/compose";
395 openMailComposeWindow(url);
398 function openMailbox(mailbox, reload, idx) {
399 if (mailbox != currentMailbox || reload) {
400 currentMailbox = mailbox;
401 var url = ApplicationBaseURL + encodeURI(mailbox) + "/view?noframe=1";
402 var messageContent = $("messageContent");
403 messageContent.update();
404 lastClickedRow = null; // from generic.js
408 currentMessage = currentMessages[mailbox];
409 if (currentMessage) {
410 loadMessage(currentMessage);
411 url += '&pageforuid=' + currentMessage;
415 var searchValue = search["value"];
416 if (searchValue && searchValue.length > 0)
417 url += ("&search=" + search["criteria"]
418 + "&value=" + escape(searchValue));
419 var sortAttribute = sorting["attribute"];
420 if (sortAttribute && sortAttribute.length > 0)
421 url += ("&sort=" + sorting["attribute"]
422 + "&asc=" + sorting["ascending"]);
424 url += "&idx=" + idx;
426 if (document.messageListAjaxRequest) {
427 document.messageListAjaxRequest.aborted = true;
428 document.messageListAjaxRequest.abort();
431 var mailboxContent = $("mailboxContent");
432 if (mailboxContent.getStyle('visibility') == "hidden") {
433 mailboxContent.setStyle({ visibility: "visible" });
434 var rightDragHandle = $("rightDragHandle");
435 rightDragHandle.setStyle({ visibility: "visible" });
436 messageContent.setStyle({ top: (rightDragHandle.offsetTop
437 + rightDragHandle.offsetHeight
440 document.messageListAjaxRequest
441 = triggerAjaxRequest(url, messageListCallback,
444 var quotasUrl = ApplicationBaseURL + mailbox + "/quotas";
445 document.quotasAjaxRequest
446 = triggerAjaxRequest(quotasUrl, quotasCallback);
450 function openMailboxAtIndex(event) {
451 openMailbox(currentMailbox, true, this.getAttribute("idx"));
456 function messageListCallback(http) {
457 var div = $('mailboxContent');
458 var table = $('messageList');
460 if (http.readyState == 4
461 && http.status == 200) {
462 document.messageListAjaxRequest = null;
466 var thead = table.tHead;
467 var tbody = table.tBodies[0];
468 var tmp = document.createElement('div');
469 $(tmp).update(http.responseText);
470 thead.rows[1].parentNode.replaceChild(tmp.firstChild.tHead.rows[1], thead.rows[1]);
471 table.replaceChild(tmp.firstChild.tBodies[0], tbody);
475 div.update(http.responseText);
476 table = $('messageList');
477 configureMessageListEvents(table);
478 TableKit.Resizable.init(table, {'trueResize' : true, 'keepWidth' : true});
480 configureMessageListBodyEvents(table);
482 var selected = http.callbackData;
484 var row = $("row_" + selected);
487 lastClickedRow = row.rowIndex - $(row).up('table').down('thead').getElementsByTagName('tr').length;
488 div.scrollTop = row.rowIndex * row.getHeight(); // scroll to selected message
491 $("messageContent").update();
496 if (sorting["attribute"] && sorting["attribute"].length > 0) {
497 var sortHeader = $(sorting["attribute"] + "Header");
500 var sortImages = $(table.tHead).getElementsByClassName("sortImage");
501 $(sortImages).each(function(item) {
505 var sortImage = createElement("img", "messageSortImage", "sortImage");
506 sortHeader.insertBefore(sortImage, sortHeader.firstChild);
507 if (sorting["ascending"])
508 sortImage.src = ResourcesURL + "/title_sortdown_12x12.png";
510 sortImage.src = ResourcesURL + "/title_sortup_12x12.png";
515 var data = http.responseText;
516 var msg = data.replace(/^(.*\n)*.*<p>((.*\n)*.*)<\/p>(.*\n)*.*$/, "$2");
517 log("messageListCallback: problem during ajax request (readyState = " + http.readyState + ", status = " + http.status + ", response = " + msg + ")");
521 function quotasCallback(http) {
522 if (http.readyState == 4
523 && http.status == 200) {
524 var hasQuotas = false;
526 var quotas = http.responseText.evalJSON(true);
527 for (var i in quotas) {
533 var treePath = currentMailbox.split("/");
534 var mbQuotas = quotas["/" + treePath[2]];
535 var used = mbQuotas["usedSpace"];
536 var max = mbQuotas["maxQuota"];
537 var percents = (Math.round(used * 10000 / max) / 100);
538 var format = labels["quotasFormat"];
539 var text = format.formatted(used, max, percents);
540 window.status = text;
545 function onMessageContextMenu(event) {
546 var menu = $('messageListMenu');
547 Event.observe(menu, "hideMenu", onMessageContextMenuHide);
548 popupMenu(event, "messageListMenu", this);
550 var topNode = $('messageList');
551 var selectedNodes = topNode.getSelectedRows();
552 for (var i = 0; i < selectedNodes.length; i++)
553 selectedNodes[i].deselect();
554 topNode.menuSelectedRows = selectedNodes;
555 topNode.menuSelectedEntry = this;
559 function onMessageContextMenuHide(event) {
560 var topNode = $('messageList');
562 if (topNode.menuSelectedEntry) {
563 topNode.menuSelectedEntry.deselect();
564 topNode.menuSelectedEntry = null;
566 if (topNode.menuSelectedRows) {
567 var nodes = topNode.menuSelectedRows;
568 for (var i = 0; i < nodes.length; i++)
570 topNode.menuSelectedRows = null;
574 function onFolderMenuClick(event) {
575 var onhide, menuName;
577 var menutype = this.parentNode.getAttribute("datatype");
579 if (menutype == "inbox") {
580 menuName = "inboxIconMenu";
581 } else if (menutype == "account") {
582 menuName = "accountIconMenu";
583 } else if (menutype == "trash") {
584 menuName = "trashIconMenu";
586 menuName = "mailboxIconMenu";
589 menuName = "mailboxIconMenu";
592 var menu = $(menuName);
593 Event.observe(menu, "hideMenu", onFolderMenuHide);
594 popupMenu(event, menuName, this.parentNode);
596 var topNode = $("mailboxTree");
597 if (topNode.selectedEntry)
598 topNode.selectedEntry.deselect();
599 if (topNode.menuSelectedEntry)
600 topNode.menuSelectedEntry.deselect();
601 topNode.menuSelectedEntry = this;
604 preventDefault(event);
607 function onFolderMenuHide(event) {
608 var topNode = $("mailboxTree");
610 if (topNode.menuSelectedEntry) {
611 topNode.menuSelectedEntry.deselect();
612 topNode.menuSelectedEntry = null;
614 if (topNode.selectedEntry)
615 topNode.selectedEntry.select();
618 function deleteCachedMessage(messageId) {
622 while (counter < cachedMessages.length
624 if (cachedMessages[counter]
625 && cachedMessages[counter]['idx'] == messageId) {
626 cachedMessages.splice(counter, 1);
633 function getCachedMessage(idx) {
637 while (counter < cachedMessages.length
639 if (cachedMessages[counter]
640 && cachedMessages[counter]['idx'] == currentMailbox + '/' + idx)
641 message = cachedMessages[counter];
648 function storeCachedMessage(cachedMessage) {
653 if (cachedMessages.length < maxCachedMessages)
654 oldest = cachedMessages.length;
656 while (cachedMessages[counter]) {
658 || cachedMessages[counter]['time'] < timeOldest) {
660 timeOldest = cachedMessages[counter]['time'];
669 cachedMessages[oldest] = cachedMessage;
672 function onMessageSelectionChange() {
673 var rows = this.getSelectedRowsId();
675 if (rows.length == 1) {
676 var idx = rows[0].substr(4);
678 if (currentMessages[currentMailbox] != idx) {
679 currentMessages[currentMailbox] = idx;
685 function loadMessage(idx) {
686 if (document.messageAjaxRequest) {
687 document.messageAjaxRequest.aborted = true;
688 document.messageAjaxRequest.abort();
691 var cachedMessage = getCachedMessage(idx);
693 if (cachedMessage == null) {
694 var url = (ApplicationBaseURL + currentMailbox + "/"
695 + idx + "/view?noframe=1");
696 document.messageAjaxRequest
697 = triggerAjaxRequest(url, messageCallback, idx);
698 markMailInWindow(window, idx, true);
700 var div = $('messageContent');
701 div.update(cachedMessage['text']);
702 cachedMessage['time'] = (new Date()).getTime();
703 document.messageAjaxRequest = null;
704 configureLinksInMessage();
709 function configureLinksInMessage() {
710 var messageDiv = $('messageContent');
711 var mailContentDiv = document.getElementsByClassName('mailer_mailcontent',
713 if (!document.body.hasClassName("popup"))
714 Event.observe(mailContentDiv, "contextmenu",
715 onMessageContentMenu.bindAsEventListener(mailContentDiv));
716 var anchors = messageDiv.getElementsByTagName('a');
717 for (var i = 0; i < anchors.length; i++)
718 if (anchors[i].href.substring(0,7) == "mailto:") {
719 Event.observe(anchors[i], "click",
720 onEmailAddressClick.bindAsEventListener(anchors[i]));
721 Event.observe(anchors[i], "contextmenu",
722 onEmailAddressClick.bindAsEventListener(anchors[i]));
725 Event.observe(anchors[i], "click",
726 onMessageAnchorClick.bindAsEventListener(anchors[i]));
728 var editDraftButton = $("editDraftButton");
730 Event.observe(editDraftButton, "click",
731 onMessageEditDraft.bindAsEventListener(editDraftButton));
734 function resizeMailContent() {
735 var headerTable = document.getElementsByClassName('mailer_fieldtable')[0];
736 var contentDiv = document.getElementsByClassName('mailer_mailcontent')[0];
738 contentDiv.setStyle({ 'top': (Element.getHeight(headerTable) + headerTable.offsetTop) + 'px' });
741 function onMessageContentMenu(event) {
742 popupMenu(event, 'messageContentMenu', this);
745 function onMessageEditDraft(event) {
746 return openMessageWindowsForSelection("edit", true);
749 function onEmailAddressClick(event) {
750 popupMenu(event, 'addressMenu', this);
753 function onMessageAnchorClick(event) {
754 window.open(this.href);
755 preventDefault(event);
758 function messageCallback(http) {
759 var div = $('messageContent');
761 if (http.readyState == 4
762 && http.status == 200) {
763 document.messageAjaxRequest = null;
764 div.update(http.responseText);
765 configureLinksInMessage();
768 if (http.callbackData) {
769 var cachedMessage = new Array();
770 cachedMessage['idx'] = currentMailbox + '/' + http.callbackData;
771 cachedMessage['time'] = (new Date()).getTime();
772 cachedMessage['text'] = http.responseText;
773 if (cachedMessage['text'].length < 30000)
774 storeCachedMessage(cachedMessage);
778 log("messageCallback: problem during ajax request: " + http.status);
781 function processMailboxMenuAction(mailbox) {
782 var currentNode, upperNode;
786 mailboxName = mailbox.getAttribute('mailboxname');
787 currentNode = mailbox;
791 && !currentNode.hasAttribute('mailboxaction'))
792 currentNode = currentNode.parentNode.parentNode.parentMenuItem;
796 action = currentNode.getAttribute('mailboxaction');
797 // var rows = collectSelectedRows();
798 // var rString = rows.join(', ');
799 // alert("performing '" + action + "' on " + rString
800 // + " to " + mailboxName);
804 var rowSelectionCount = 0;
808 function showElement(e, shouldShow) {
809 e.style.display = shouldShow ? "" : "none";
812 function enableElement(e, shouldEnable) {
816 if(e.hasAttribute("disabled"))
817 e.removeAttribute("disabled");
820 e.setAttribute("disabled", "1");
824 function validateControls() {
826 this.enableElement(e, rowSelectionCount > 0);
829 function moveTo(uri) {
830 alert("MoveTo: " + uri);
833 /* message menu entries */
834 function onMenuOpenMessage(event) {
835 return openMessageWindowsForSelection('popupview');
838 function onMenuReplyToSender(event) {
839 return openMessageWindowsForSelection('reply');
842 function onMenuReplyToAll(event) {
843 return openMessageWindowsForSelection('replyall');
846 function onMenuForwardMessage(event) {
847 return openMessageWindowsForSelection('forward');
850 function onMenuViewMessageSource(event) {
851 var messageList = $("messageList");
852 var rows = messageList.getSelectedRowsId();
854 if (rows.length > 0) {
855 var url = (ApplicationBaseURL + currentMailbox + "/"
856 + rows[0].substr(4) + "/viewsource");
857 openMailComposeWindow(url);
860 preventDefault(event);
864 function newContactFromEmail(event) {
865 var mailto = document.menuTarget.innerHTML;
867 var email = extractEmailAddress(mailto);
868 var c_name = extractEmailName(mailto);
869 if (email.length > 0)
871 var url = UserFolderURL + "Contacts/new?contactEmail=" + email;
873 url += "&contactFN=" + c_name;
874 openContactWindow(url);
877 return false; /* stop following the link */
880 function newEmailTo(sender) {
881 return openMailTo(document.menuTarget.innerHTML);
884 function expandUpperTree(node) {
885 var currentNode = node.parentNode;
887 while (currentNode.className != "dtree") {
888 if (currentNode.className == 'clip') {
889 var id = currentNode.getAttribute("id");
890 var number = parseInt(id.substr(2));
892 var cn = mailboxTree.aNodes[number];
893 mailboxTree.nodeStatus(1, number, cn._ls);
896 currentNode = currentNode.parentNode;
900 function onHeaderClick(event) {
901 var headerId = this.getAttribute("id");
902 var newSortAttribute;
903 if (headerId == "subjectHeader")
904 newSortAttribute = "subject";
905 else if (headerId == "fromHeader")
906 newSortAttribute = "from";
907 else if (headerId == "dateHeader")
908 newSortAttribute = "date";
910 newSortAttribute = "arrival";
912 if (sorting["attribute"] == newSortAttribute)
913 sorting["ascending"] = !sorting["ascending"];
915 sorting["attribute"] = newSortAttribute;
916 sorting["ascending"] = true;
918 refreshCurrentFolder();
923 function refreshCurrentFolder() {
924 openMailbox(currentMailbox, true);
927 function refreshFolderByType(type) {
928 if (currentMailboxType == type)
929 refreshCurrentFolder();
932 var mailboxSpanAcceptType = function(type) {
933 return (type == "mailRow");
936 var mailboxSpanEnter = function() {
937 this.addClassName("_dragOver");
940 var mailboxSpanExit = function() {
941 this.removeClassName("_dragOver");
944 var mailboxSpanDrop = function(data) {
948 var folder = this.parentNode.parentNode.getAttribute("dataname");
949 if (folder != currentMailbox)
950 success = (moveMessages(data, folder) == 0);
958 var plusSignEnter = function() {
959 var nodeNr = parseInt(this.id.substr(2));
960 if (!mailboxTree.aNodes[nodeNr]._io)
961 this.plusSignTimer = setTimeout("openPlusSign('" + nodeNr + "');", 1000);
964 var plusSignExit = function() {
965 if (this.plusSignTimer) {
966 clearTimeout(this.plusSignTimer);
967 this.plusSignTimer = null;
971 function openPlusSign(nodeNr) {
972 mailboxTree.nodeStatus(1, nodeNr, mailboxTree.aNodes[nodeNr]._ls);
973 mailboxTree.aNodes[nodeNr]._io = 1;
974 this.plusSignTimer = null;
977 var messageListGhost = function () {
978 var newDiv = document.createElement("div");
979 // newDiv.style.width = "25px;";
980 // newDiv.style.height = "25px;";
981 newDiv.style.backgroundColor = "#aae;";
982 newDiv.style.border = "2px solid #a3a;";
983 newDiv.style.padding = "5px;";
984 newDiv.ghostOffsetX = 10;
985 newDiv.ghostOffsetY = 5;
987 var newImg = document.createElement("img");
988 newImg.src = ResourcesURL + "/message-mail.png";
990 var list = $("messageList");
991 var count = list.getSelectedRows().length;
992 newDiv.appendChild(newImg);
993 newDiv.appendChild(document.createElement("br"));
994 newDiv.appendChild(document.createTextNode(count + " messages..."));
999 var messageListData = function(type) {
1000 var rows = this.parentNode.parentNode.getSelectedRowsId();
1001 var msgIds = new Array();
1002 for (var i = 0; i < rows.length; i++)
1003 msgIds.push(rows[i].substr(4));
1008 /* a model for a futur refactoring of the sortable table headers mechanism */
1009 function configureMessageListEvents(table) {
1011 table.multiselect = true;
1012 // Each body row can load a message
1013 Event.observe(table, "mousedown",
1014 onMessageSelectionChange.bindAsEventListener(table));
1016 configureSortableTableHeaders(table);
1020 function configureMessageListBodyEvents(table) {
1023 var cell = table.tHead.rows[1].cells[0];
1024 if ($(cell).hasClassName("tbtv_navcell")) {
1025 var anchors = $(cell).childNodesWithTag("a");
1026 for (var i = 0; i < anchors.length; i++)
1027 Event.observe(anchors[i], "click", openMailboxAtIndex.bindAsEventListener(anchors[i]));
1030 rows = table.tBodies[0].rows;
1031 for (var i = 0; i < rows.length; i++) {
1032 Event.observe(rows[i], "mousedown", onRowClick);
1033 Event.observe(rows[i], "selectstart", listRowMouseDownHandler);
1034 Event.observe(rows[i], "contextmenu", onMessageContextMenu.bindAsEventListener(rows[i]));
1036 rows[i].dndTypes = function() { return new Array("mailRow"); };
1037 rows[i].dndGhost = messageListGhost;
1038 rows[i].dndDataForType = messageListData;
1039 // document.DNDManager.registerSource(rows[i]);
1041 for (var j = 0; j < rows[i].cells.length; j++) {
1042 var cell = rows[i].cells[j];
1043 Event.observe(cell, "mousedown", listRowMouseDownHandler);
1044 if (j == 2 || j == 3 || j == 5)
1045 Event.observe(cell, "dblclick", onMessageDoubleClick.bindAsEventListener(cell));
1047 var img = cell.childNodesWithTag("img")[0];
1048 Event.observe(img, "click", mailListMarkMessage);
1055 function configureDragHandles() {
1056 var handle = $("verticalDragHandle");
1058 handle.addInterface(SOGoDragHandlesInterface);
1059 handle.leftMargin = 1;
1060 handle.leftBlock=$("leftPanel");
1061 handle.rightBlock=$("rightPanel");
1064 handle = $("rightDragHandle");
1066 handle.addInterface(SOGoDragHandlesInterface);
1067 handle.upperBlock=$("mailboxContent");
1068 handle.lowerBlock=$("messageContent");
1073 function initDnd() {
1074 // log("MailerUI initDnd");
1076 var tree = $("mailboxTree");
1078 var images = tree.getElementsByTagName("img");
1079 for (var i = 0; i < images.length; i++) {
1080 if (images[i].id[0] == 'j') {
1081 images[i].dndAcceptType = mailboxSpanAcceptType;
1082 images[i].dndEnter = plusSignEnter;
1083 images[i].dndExit = plusSignExit;
1084 document.DNDManager.registerDestination(images[i]);
1087 var nodes = document.getElementsByClassName("nodeName", tree);
1088 for (var i = 0; i < nodes.length; i++) {
1089 nodes[i].dndAcceptType = mailboxSpanAcceptType;
1090 nodes[i].dndEnter = mailboxSpanEnter;
1091 nodes[i].dndExit = mailboxSpanExit;
1092 nodes[i].dndDrop = mailboxSpanDrop;
1093 document.DNDManager.registerDestination(nodes[i]);
1100 function refreshContacts() {
1103 function openInbox(node) {
1105 openMailbox(node.parentNode.getAttribute("dataname"));
1106 var tree = $("mailboxTree");
1107 tree.selectedEntry = node;
1112 function initMailer(event) {
1113 if (!document.body.hasClassName("popup")) {
1116 initMessageCheckTimer();
1120 function initMessageCheckTimer() {
1121 var messageCheck = userDefaults["MessageCheck"];
1122 if (messageCheck && messageCheck != "manually") {
1124 if (messageCheck == "once_per_hour")
1126 else if (messageCheck == "every_minute")
1129 interval = parseInt(messageCheck.substr(6)) * 60;
1131 messageCheckTimer = window.setInterval(onMessageCheckCallback,
1136 function onMessageCheckCallback(event) {
1140 function initMailboxTree() {
1141 mailboxTree = new dTree("mailboxTree");
1142 mailboxTree.config.folderLinks = true;
1143 mailboxTree.config.hideRoot = true;
1145 mailboxTree.icon.root = ResourcesURL + "/tbtv_account_17x17.gif";
1146 mailboxTree.icon.folder = ResourcesURL + "/tbtv_leaf_corner_17x17.gif";
1147 mailboxTree.icon.folderOpen = ResourcesURL + "/tbtv_leaf_corner_17x17.gif";
1148 mailboxTree.icon.node = ResourcesURL + "/tbtv_leaf_corner_17x17.gif";
1149 mailboxTree.icon.line = ResourcesURL + "/tbtv_line_17x17.gif";
1150 mailboxTree.icon.join = ResourcesURL + "/tbtv_junction_17x17.gif";
1151 mailboxTree.icon.joinBottom = ResourcesURL + "/tbtv_corner_17x17.gif";
1152 mailboxTree.icon.plus = ResourcesURL + "/tbtv_plus_17x17.gif";
1153 mailboxTree.icon.plusBottom = ResourcesURL + "/tbtv_corner_plus_17x17.gif";
1154 mailboxTree.icon.minus = ResourcesURL + "/tbtv_minus_17x17.gif";
1155 mailboxTree.icon.minusBottom = ResourcesURL + "/tbtv_corner_minus_17x17.gif";
1156 mailboxTree.icon.nlPlus = ResourcesURL + "/tbtv_corner_plus_17x17.gif";
1157 mailboxTree.icon.nlMinus = ResourcesURL + "/tbtv_corner_minus_17x17.gif";
1158 mailboxTree.icon.empty = ResourcesURL + "/empty.gif";
1160 mailboxTree.add(0, -1, '');
1162 mailboxTree.pendingRequests = mailAccounts.length;
1163 activeAjaxRequests += mailAccounts.length;
1164 for (var i = 0; i < mailAccounts.length; i++) {
1165 var url = ApplicationBaseURL + "/" + mailAccounts[i] + "/mailboxes";
1166 triggerAjaxRequest(url, onLoadMailboxesCallback, mailAccounts[i]);
1170 function updateMailboxTreeInPage() {
1171 $("folderTreeContent").update(mailboxTree);
1173 var inboxFound = false;
1174 var tree = $("mailboxTree");
1175 var nodes = document.getElementsByClassName("node", tree);
1176 for (i = 0; i < nodes.length; i++) {
1177 Event.observe(nodes[i], "click",
1178 onMailboxTreeItemClick.bindAsEventListener(nodes[i]));
1179 Event.observe(nodes[i], "contextmenu",
1180 onFolderMenuClick.bindAsEventListener(nodes[i]));
1182 && nodes[i].parentNode.getAttribute("datatype") == "inbox") {
1183 openInbox(nodes[i]);
1189 function mailboxMenuNode(type, name) {
1190 var newNode = document.createElement("li");
1191 var icon = MailerUIdTreeExtension.folderIcons[type];
1193 icon = "tbtv_leaf_corner_17x17.gif";
1194 var image = document.createElement("img");
1195 image.src = ResourcesURL + "/" + icon;
1196 newNode.appendChild(image);
1197 var displayName = MailerUIdTreeExtension.folderNames[type];
1200 newNode.appendChild(document.createTextNode(" " + displayName));
1205 function generateMenuForMailbox(mailbox, prefix, callback) {
1206 var menuDIV = document.createElement("div");
1207 $(menuDIV).addClassName("menu");
1208 menuDIV.setAttribute("id", prefix + "Submenu");
1209 var menu = document.createElement("ul");
1210 menuDIV.appendChild(menu);
1211 pageContent.appendChild(menuDIV);
1213 var callbacks = new Array();
1214 if (mailbox.type != "account") {
1215 var newNode = document.createElement("li");
1216 newNode.mailbox = mailbox;
1217 newNode.appendChild(document.createTextNode(labels["This Folder"]));
1218 menu.appendChild(newNode);
1219 menu.appendChild(document.createElement("li"));
1220 callbacks.push(callback);
1221 callbacks.push("-");
1224 var submenuCount = 0;
1225 for (var i = 0; i < mailbox.children.length; i++) {
1226 var child = mailbox.children[i];
1227 var newNode = mailboxMenuNode(child.type, child.name);
1228 menu.appendChild(newNode);
1229 if (child.children.length > 0) {
1230 var newPrefix = prefix + submenuCount;
1231 var newSubmenuId = generateMenuForMailbox(child, newPrefix, callback);
1232 callbacks.push(newSubmenuId);
1236 newNode.mailbox = child;
1237 callbacks.push(callback);
1240 initMenu(menuDIV, callbacks);
1242 return menuDIV.getAttribute("id");
1245 function updateMailboxMenus() {
1246 var mailboxActions = { move: onMailboxMenuMove,
1247 copy: onMailboxMenuCopy };
1249 for (key in mailboxActions) {
1250 var menuId = key + "MailboxMenu";
1251 var menuDIV = $(menuId);
1253 menuDIV.parentNode.removeChild(menuDIV);
1255 menuDIV = document.createElement("div");
1256 pageContent = $("pageContent");
1257 pageContent.appendChild(menuDIV);
1259 var menu = document.createElement("ul");
1260 menuDIV.appendChild(menu);
1262 $(menuDIV).addClassName("menu");
1263 menuDIV.setAttribute("id", menuId);
1265 var submenuIds = new Array();
1266 for (var i = 0; i < mailAccounts.length; i++) {
1267 var menuEntry = mailboxMenuNode("account", mailAccounts[i]);
1268 menu.appendChild(menuEntry);
1269 var mailbox = accounts[mailAccounts[i]];
1270 var newSubmenuId = generateMenuForMailbox(mailbox,
1271 key, mailboxActions[key]);
1272 submenuIds.push(newSubmenuId);
1274 initMenu(menuDIV, submenuIds);
1278 function onLoadMailboxesCallback(http) {
1279 if (http.readyState == 4
1280 && http.status == 200) {
1281 checkAjaxRequestsState();
1282 var newAccount = buildMailboxes(http.callbackData,
1284 accounts[http.callbackData] = newAccount;
1285 mailboxTree.addMailAccount(newAccount);
1286 mailboxTree.pendingRequests--;
1287 activeAjaxRequests--;
1288 if (!mailboxTree.pendingRequests) {
1289 updateMailboxTreeInPage();
1290 updateMailboxMenus();
1291 checkAjaxRequestsState();
1295 // var tree = $("mailboxTree");
1296 // var treeNodes = document.getElementsByClassName("dTreeNode", tree);
1298 // while (i < treeNodes.length
1299 // && treeNodes[i].getAttribute("dataname") != currentMailbox)
1301 // if (i < treeNodes.length) {
1302 // // log("found mailbox");
1303 // var links = document.getElementsByClassName("node", treeNodes[i]);
1304 // if (tree.selectedEntry)
1305 // tree.selectedEntry.deselect();
1306 // links[0].select();
1307 // tree.selectedEntry = links[0];
1308 // expandUpperTree(links[0]);
1312 function buildMailboxes(accountName, encoded) {
1313 var account = new Mailbox("account", accountName);
1314 var data = encoded.evalJSON(true);
1315 for (var i = 0; i < data.length; i++) {
1316 var currentNode = account;
1317 var names = data[i].path.split("/");
1318 for (var j = 1; j < (names.length - 1); j++) {
1319 var node = currentNode.findMailboxByName(names[j]);
1321 node = new Mailbox("additional", names[j]);
1322 currentNode.addMailbox(node);
1326 var basename = names[names.length-1];
1327 var leaf = currentNode.findMailboxByName(basename);
1329 leaf.type = data[i].type;
1331 leaf = new Mailbox(data[i].type, basename);
1332 currentNode.addMailbox(leaf);
1339 function onMenuCreateFolder(event) {
1340 var name = window.prompt(labels["Name :"], "");
1341 if (name && name.length > 0) {
1342 var folderID = document.menuTarget.getAttribute("dataname");
1343 var urlstr = URLForFolderID(folderID) + "/createFolder?name=" + name; log ("create " + urlstr);
1344 triggerAjaxRequest(urlstr, folderOperationCallback);
1348 function onMenuRenameFolder(event) {
1349 var name = window.prompt(labels["Enter the new name of your folder :"]
1352 if (name && name.length > 0) {
1353 var folderID = document.menuTarget.getAttribute("dataname");
1354 var urlstr = URLForFolderID(folderID) + "/renameFolder?name=" + name;
1355 triggerAjaxRequest(urlstr, folderOperationCallback);
1359 function onMenuDeleteFolder(event) {
1360 var answer = window.confirm(labels["Do you really want to move this folder into the trash ?"]);
1362 var folderID = document.menuTarget.getAttribute("dataname");
1363 var urlstr = URLForFolderID(folderID) + "/deleteFolder";
1364 triggerAjaxRequest(urlstr, folderOperationCallback);
1368 function onMenuExpungeFolder(event) {
1369 var folderID = document.menuTarget.getAttribute("dataname");
1370 var urlstr = URLForFolderID(folderID) + "/expunge";
1371 triggerAjaxRequest(urlstr, folderRefreshCallback, folderID);
1374 function onMenuEmptyTrash(event) {
1375 var folderID = document.menuTarget.getAttribute("dataname");
1376 var urlstr = URLForFolderID(folderID) + "/emptyTrash";
1377 triggerAjaxRequest(urlstr, folderOperationCallback, folderID);
1379 if (folderID == currentMailbox) {
1380 var div = $('messageContent');
1381 for (var i = div.childNodes.length - 1; i > -1; i--)
1382 div.removeChild(div.childNodes[i]);
1383 refreshCurrentFolder();
1385 var msgID = currentMessages[folderID];
1387 deleteCachedMessage(folderID + "/" + msgID);
1390 function _onMenuChangeToXXXFolder(event, folder) {
1391 var type = document.menuTarget.getAttribute("datatype");
1392 if (type == "additional")
1393 window.alert(labels["You need to choose a non-virtual folder!"]);
1395 var folderID = document.menuTarget.getAttribute("dataname");
1396 var number = folderID.split("/").length;
1398 window.alert(labels["You need to choose a root subfolder!"]);
1400 var urlstr = URLForFolderID(folderID) + "/setAs" + folder + "Folder";
1401 triggerAjaxRequest(urlstr, folderOperationCallback);
1406 function onMenuChangeToDraftsFolder(event) {
1407 return _onMenuChangeToXXXFolder(event, "Drafts");
1410 function onMenuChangeToSentFolder(event) {
1411 return _onMenuChangeToXXXFolder(event, "Sent");
1414 function onMenuChangeToTrashFolder(event) {
1415 return _onMenuChangeToXXXFolder(event, "Trash");
1418 function onMenuLabelNone() {
1419 var rowId = document.menuTarget.getAttribute("id").substr(4);
1420 var messageId = currentMailbox + "/" + rowId;
1421 var urlstr = ApplicationBaseURL + messageId + "/removeAllLabels";
1422 triggerAjaxRequest(urlstr, messageFlagCallback,
1423 { mailbox: currentMailbox, msg: rowId, label: null } );
1426 function _onMenuLabelFlagX(flag) {
1427 var flags = document.menuTarget.getAttribute("labels").split(" ");
1429 var rowId = document.menuTarget.getAttribute("id").substr(4);
1430 var messageId = currentMailbox + "/" + rowId;
1432 var operation = "add";
1433 if (flags.indexOf("label" + flag) > -1)
1434 operation = "remove";
1435 var urlstr = (ApplicationBaseURL + messageId
1436 + "/" + operation + "Label" + flag);
1437 triggerAjaxRequest(urlstr, messageFlagCallback,
1438 { mailbox: currentMailbox, msg: rowId,
1439 label: operation + flag } );
1442 function onMenuLabelFlag1() {
1443 _onMenuLabelFlagX(1);
1446 function onMenuLabelFlag2() {
1447 _onMenuLabelFlagX(2);
1450 function onMenuLabelFlag3() {
1451 _onMenuLabelFlagX(3);
1454 function onMenuLabelFlag4() {
1455 _onMenuLabelFlagX(4);
1458 function onMenuLabelFlag5() {
1459 _onMenuLabelFlagX(5);
1462 function folderOperationCallback(http) {
1463 if (http.readyState == 4
1464 && isHttpStatus204(http.status))
1467 window.alert(labels["Operation failed"]);
1470 function folderRefreshCallback(http) {
1471 if (http.readyState == 4
1472 && isHttpStatus204(http.status)) {
1473 var oldMailbox = http.callbackData;
1474 if (oldMailbox == currentMailbox)
1475 refreshCurrentFolder();
1478 window.alert(labels["Operation failed"]);
1481 function messageFlagCallback(http) {
1482 if (http.readyState == 4
1483 && isHttpStatus204(http.status)) {
1484 var data = http.callbackData;
1485 if (data["mailbox"] == currentMailbox) {
1486 var row = $("row_" + data["msg"]);
1487 var operation = data["label"];
1489 var labels = row.getAttribute("labels");
1491 if (labels.length > 0)
1492 flags = labels.split(" ");
1494 flags = new Array();
1495 if (operation.substr(0, 3) == "add")
1496 flags.push("label" + operation.substr(3));
1498 var flag = "label" + operation.substr(6);
1499 var idx = flags.indexOf(flag);
1500 flags.splice(idx, 1);
1502 row.setAttribute("labels", flags.join(" "));
1505 row.setAttribute("labels", "");
1510 function onLabelMenuPrepareVisibility() {
1511 var messageList = $("messageList");
1515 var rows = messageList.getSelectedRows();
1516 for (var i = 0; i < rows.length; i++) {
1517 $w(rows[i].getAttribute("labels")).each(function(flag) {
1523 var lis = this.childNodesWithTag("ul")[0].childNodesWithTag("li")
1524 var isFlagged = false;
1525 for (var i = 1; i < 6; i++) {
1526 if (flags["label" + i]) {
1528 lis[1 + i].addClassName("_chosen");
1531 lis[1 + i].removeClassName("_chosen");
1534 lis[0].removeClassName("_chosen");
1536 lis[0].addClassName("_chosen");
1539 function getMenus() {
1541 menus["accountIconMenu"] = new Array(null, null, onMenuCreateFolder, null,
1543 menus["inboxIconMenu"] = new Array(null, null, null, "-", null,
1544 onMenuCreateFolder, onMenuExpungeFolder,
1547 menus["trashIconMenu"] = new Array(null, null, null, "-", null,
1548 onMenuCreateFolder, onMenuExpungeFolder,
1549 onMenuEmptyTrash, "-", null,
1551 menus["mailboxIconMenu"] = new Array(null, null, null, "-", null,
1554 onMenuExpungeFolder,
1559 menus["addressMenu"] = new Array(newContactFromEmail, newEmailTo, null);
1560 menus["messageListMenu"] = new Array(onMenuOpenMessage, "-",
1561 onMenuReplyToSender,
1563 onMenuForwardMessage, null,
1564 "-", "moveMailboxMenu",
1565 "copyMailboxMenu", "label-menu",
1566 "mark-menu", "-", null,
1567 onMenuViewMessageSource, null,
1568 null, onMenuDeleteMessage);
1569 menus["messageContentMenu"] = new Array(onMenuReplyToSender,
1571 onMenuForwardMessage,
1572 null, "moveMailboxMenu",
1574 "-", "label-menu", "mark-menu",
1576 null, onMenuViewMessageSource,
1577 null, onPrintCurrentMessage,
1578 onMenuDeleteMessage);
1579 menus["folderTypeMenu"] = new Array(onMenuChangeToSentFolder,
1580 onMenuChangeToDraftsFolder,
1581 onMenuChangeToTrashFolder);
1583 menus["label-menu"] = new Array(onMenuLabelNone, "-", onMenuLabelFlag1,
1584 onMenuLabelFlag2, onMenuLabelFlag3,
1585 onMenuLabelFlag4, onMenuLabelFlag5);
1586 menus["mark-menu"] = new Array(null, null, null, null, "-", null, "-",
1588 menus["searchMenu"] = new Array(setSearchCriteria, setSearchCriteria,
1589 setSearchCriteria, setSearchCriteria,
1591 var labelMenu = $("label-menu");
1593 labelMenu.prepareVisibility = onLabelMenuPrepareVisibility;
1598 addEvent(window, 'load', initMailer);
1600 function Mailbox(type, name) {
1603 this.parentFolder = null;
1604 this.children = new Array();
1608 Mailbox.prototype.dump = function(indent) {
1611 log(" ".repeat(indent) + this.name);
1612 for (var i = 0; i < this.children.length; i++) {
1613 this.children[i].dump(indent + 2);
1617 Mailbox.prototype.fullName = function() {
1620 var currentFolder = this;
1621 while (currentFolder.parentFolder) {
1622 fullName = "/folder" + currentFolder.name + fullName;
1623 currentFolder = currentFolder.parentFolder;
1626 return "/" + currentFolder.name + fullName;
1629 Mailbox.prototype.findMailboxByName = function(name) {
1633 while (!mailbox && i < this.children.length)
1634 if (this.children[i].name == name)
1635 mailbox = this.children[i];
1642 Mailbox.prototype.addMailbox = function(mailbox) {
1643 mailbox.parentFolder = this;
1644 this.children.push(mailbox);