]> err.no Git - scalable-opengroupware.org/blob - UI/WebServerResources/MailerUI.js
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1210 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / UI / WebServerResources / MailerUI.js
1 /* JavaScript for SOGoMail */
2 var accounts = {};
3 var mailboxTree;
4 var mailAccounts;
5 if (typeof textMailAccounts != 'undefined')
6   mailAccounts = textMailAccounts.evalJSON(true);
7
8 var currentMessages = new Array();
9 var maxCachedMessages = 20;
10 var cachedMessages = new Array();
11 var currentMailbox = null;
12 var currentMailboxType = "";
13
14 var usersRightsWindowHeight = 320;
15 var usersRightsWindowWidth = 400;
16
17 var pageContent;
18
19 var deleteMessageRequestCount = 0;
20
21 var messageCheckTimer;
22
23 /* mail list */
24
25 function openMessageWindow(msguid, url) {
26   var wId = '';
27   if (msguid) {
28     wId += "SOGo_msg_" + msguid;
29     markMailReadInWindow(window, msguid);
30   }
31   var msgWin = openMailComposeWindow(url, wId);
32   msgWin.focus();
33
34   return false;
35 }
36
37 function onMessageDoubleClick(event) {
38   var action;
39
40   if (currentMailboxType == "draft")
41     action = "edit";
42   else
43     action = "popupview";
44
45   return openMessageWindowsForSelection(action, true);
46 }
47
48 function toggleMailSelect(sender) {
49   var row;
50   row = $(sender.name);
51   row.className = sender.checked ? "tableview_selected" : "tableview";
52 }
53
54 function openAddressbook(sender) {
55   var urlstr;
56    
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");
61   w.focus();
62
63   return false;
64 }
65
66 function onMenuSharing(event) {
67   var folderID = document.menuTarget.getAttribute("dataname");
68   var type = document.menuTarget.getAttribute("datatype");
69
70   if (type == "additional")
71     window.alert(clabels["The user rights cannot be"
72                          + " edited for this object!"]);
73   else {
74     var urlstr = URLForFolderID(folderID) + "/acls";
75     openAclWindow(urlstr);
76   }
77 }
78
79 /* mail list DOM changes */
80
81 function markMailInWindow(win, msguid, markread) {
82   var msgDiv;
83
84   msgDiv = win.$("div_" + msguid);
85   if (msgDiv) {
86     if (markread) {
87       msgDiv.removeClassName("mailer_unreadmailsubject");
88       msgDiv.addClassName("mailer_readmailsubject");
89       msgDiv = win.$("unreaddiv_" + msguid);
90       if (msgDiv)
91         {
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
97                               + ", false);"
98                               +" return false;");
99           var title = msgDiv.getAttribute("title-markunread");
100           if (title)
101             msgDiv.setAttribute("title", title);
102         }
103     }
104     else {
105       msgDiv.removeClassName('mailer_readmailsubject');
106       msgDiv.addClassName('mailer_unreadmailsubject');
107       msgDiv = win.$("readdiv_" + msguid);
108       if (msgDiv)
109         {
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
115                               + ", true);"
116                               +" return false;");
117           var title = msgDiv.getAttribute("title-markread");
118           if (title)
119             msgDiv.setAttribute("title", title);
120         }
121     }
122     return true;
123   }
124   else
125     return false;
126 }
127
128 function markMailReadInWindow(win, msguid) {
129   /* this is called by UIxMailView with window.opener */
130   return markMailInWindow(win, msguid, true);
131 }
132
133 /* mail list reply */
134
135 function openMessageWindowsForSelection(action, firstOnly) {
136   if (document.body.hasClassName("popup")) {
137     return true;
138   }
139   else {
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)
147                           + "/" + action);
148         if (firstOnly)
149           break;
150       }
151     } else {
152       window.alert(labels["Please select a message."]);
153     }
154   }
155
156   return false;
157 }
158
159 function mailListMarkMessage(event) {
160   var http = createHTTPClient();
161   var url = ApplicationBaseURL + currentMailbox + "/" + msguid + "/" + action;
162
163   if (http) {
164     // TODO: add parameter to signal that we are only interested in OK
165     http.open("POST", url, false /* not async */);
166     http.send("");
167     if (http.status != 200) {
168       // TODO: refresh page?
169       alert("Message Mark Failed: " + http.statusText);
170       window.location.reload();
171     }
172     else {
173       markMailInWindow(window, msguid, markread);
174     }
175   }
176   else {
177     window.location.href = url;
178   }
179 }
180
181 /* maillist row highlight */
182
183 var oldMaillistHighlight = null; // to remember deleted/selected style
184
185 function ml_highlight(sender) {
186   oldMaillistHighlight = sender.className;
187   if (oldMaillistHighlight == "tableview_highlight")
188     oldMaillistHighlight = null;
189   sender.className = "tableview_highlight";
190 }
191
192 function ml_lowlight(sender) {
193   if (oldMaillistHighlight) {
194     sender.className = oldMaillistHighlight;
195     oldMaillistHighlight = null;
196   }
197   else
198     sender.className = "tableview";
199 }
200
201
202 /* bulk delete of messages */
203
204 function deleteSelectedMessages(sender) {
205   var messageList = $("messageList");
206   var rowIds = messageList.getSelectedRowsId();
207
208   for (var i = 0; i < rowIds.length; i++) {
209     var url, http;
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);
216   }
217
218   return false;
219 }
220
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"]) {
227         
228         var div = $('messageContent');
229         if (currentMessages[currentMailbox] == data["id"]) {
230           div.update();
231           currentMessages[currentMailbox] = null;       
232         }
233
234         var row = $("row_" + data["id"]);
235         row.parentNode.removeChild(row);
236 //      row.addClassName("deleted"); // when we'll offer "mark as deleted"
237
238         deleteMessageRequestCount--;
239       }
240     }
241   }
242   else
243     log ("deleteSelectedMessagesCallback: problem during ajax request " + http.status);
244 }
245
246 function deleteDraft(url) {
247   /* this is called by UIxMailEditor with window.opener */
248   new Ajax.Request(url, {
249     method: 'post',
250     onFailure: function(transport) {
251         if (!isHttpStatus204)
252           log("draftDeleteCallback: problem during ajax request: " + transport.status);
253       }
254     });
255 }
256
257 function moveMessages(rowIds, folder) {
258   var failCount = 0;
259
260   for (var i = 0; i < rowIds.length; i++) {
261     var url, http;
262
263     /* send AJAX request (synchronously) */
264           
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 */);
270     http.send("");
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');
277         div.update();
278         currentMessages[currentMailbox] = null;
279       }
280     }
281     else /* request failed */
282       failCount++;
283
284     /* remove from page */
285
286     /* line-through would be nicer, but hiding is OK too */
287   }
288
289   if (failCount > 0)
290     alert("Could not move " + failCount + " messages!");
291    
292   return failCount;
293 }
294
295 function onMenuDeleteMessage(event) {
296   deleteSelectedMessages();
297   preventDefault(event);
298 }
299
300 function onPrintCurrentMessage(event) {
301   var rowIds = $("messageList").getSelectedRowsId();
302   if (rowIds.length == 0) {
303     window.alert(labels["Please select a message to print."]);
304   }
305   else if (rowIds.length > 1) {
306     window.alert(labels["Please select only one message to print."]);
307   }
308   else
309     window.print();
310
311   preventDefault(event);
312 }
313
314 function onMailboxTreeItemClick(event) {
315   var topNode = $("mailboxTree");
316   var mailbox = this.parentNode.getAttribute("dataname");
317
318   if (topNode.selectedEntry)
319     topNode.selectedEntry.deselect();
320   this.select();
321   topNode.selectedEntry = this;
322
323   search = {};
324   sorting = {};
325   $("searchValue").value = "";
326   initCriteria();
327
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--)
336       body.deleteRow(i-1);
337     if (head.rows[1])
338       head.rows[1].firstChild.update();
339   }
340   else
341     openMailbox(mailbox);
342    
343   Event.stop(event);
344 }
345
346 function _onMailboxMenuAction(menuEntry, error, actionName) {
347   var targetMailbox = menuEntry.mailbox.fullName();
348
349   if (targetMailbox == currentMailbox)
350     window.alert(labels[error]);
351   else {
352     var message;
353     if (document.menuTarget.tagName == "DIV")
354       message = currentMessages[currentMailbox];
355     else
356       message = document.menuTarget.getAttribute("id").substr(4);
357
358     var urlstr = (URLForFolderID(currentMailbox) + "/" + message
359                   + "/" + actionName + "?folder=" + targetMailbox);
360     triggerAjaxRequest(urlstr, folderRefreshCallback, currentMailbox);
361   }
362 }
363
364 function onMailboxMenuMove(event) {
365   _onMailboxMenuAction(this,
366                        "Moving a message into its own folder is impossible!",
367                        "move");
368 }
369
370 function onMailboxMenuCopy(event) {
371   _onMailboxMenuAction(this,
372                        "Copying a message into its own folder is impossible!",
373                        "copy");
374 }
375
376 function refreshMailbox() {
377   var topWindow = getTopWindow();
378   if (topWindow)
379     topWindow.refreshCurrentFolder();
380
381   return false;
382 }
383
384 function onComposeMessage() {
385   var topWindow = getTopWindow();
386   if (topWindow)
387     topWindow.composeNewMessage();
388
389   return false;
390 }
391
392 function composeNewMessage() {
393   var account = currentMailbox.split("/")[1];
394   var url = ApplicationBaseURL + "/" + account + "/compose";
395   openMailComposeWindow(url);
396 }
397
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
405
406     var currentMessage;
407     if (!idx) {
408       currentMessage = currentMessages[mailbox];
409       if (currentMessage) {
410         loadMessage(currentMessage);
411         url += '&pageforuid=' + currentMessage;
412       }
413     }
414
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"]);
423     if (idx)
424       url += "&idx=" + idx;
425
426     if (document.messageListAjaxRequest) {
427       document.messageListAjaxRequest.aborted = true;
428       document.messageListAjaxRequest.abort();
429     }
430
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
438                                       + 'px') });
439     }
440     document.messageListAjaxRequest
441       = triggerAjaxRequest(url, messageListCallback,
442                            currentMessage);
443
444     var quotasUrl = ApplicationBaseURL + mailbox + "/quotas";
445     document.quotasAjaxRequest
446       = triggerAjaxRequest(quotasUrl, quotasCallback);
447   }
448 }
449
450 function openMailboxAtIndex(event) {
451   openMailbox(currentMailbox, true, this.getAttribute("idx"));
452
453   Event.stop(event);
454 }
455
456 function messageListCallback(http) {
457   var div = $('mailboxContent');
458   var table = $('messageList');
459   
460   if (http.readyState == 4
461       && http.status == 200) {
462     document.messageListAjaxRequest = null;    
463
464     if (table) {
465       // Update table
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);
472     }
473     else {
474       // Add table
475       div.update(http.responseText);
476       table = $('messageList');
477       configureMessageListEvents(table);
478       TableKit.Resizable.init(table, {'trueResize' : true, 'keepWidth' : true});
479     }
480     configureMessageListBodyEvents(table);
481
482     var selected = http.callbackData;
483     if (selected) {
484       var row = $("row_" + selected);
485       if (row) {
486         row.select();
487         lastClickedRow = row.rowIndex - $(row).up('table').down('thead').getElementsByTagName('tr').length;  
488         div.scrollTop = row.rowIndex * row.getHeight(); // scroll to selected message
489       }
490       else
491         $("messageContent").update();
492     }
493     else
494       div.scrollTop = 0;
495     
496     if (sorting["attribute"] && sorting["attribute"].length > 0) {
497       var sortHeader = $(sorting["attribute"] + "Header");
498       
499       if (sortHeader) {
500         var sortImages = $(table.tHead).getElementsByClassName("sortImage");
501         $(sortImages).each(function(item) {
502             item.remove();
503           });
504
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";
509         else
510           sortImage.src = ResourcesURL + "/title_sortup_12x12.png";
511       }
512     }
513   }
514   else {
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 + ")");
518   }
519 }
520
521 function quotasCallback(http) {
522   if (http.readyState == 4
523       && http.status == 200) {
524     var hasQuotas = false;
525
526     var quotas = http.responseText.evalJSON(true);
527     for (var i in quotas) {
528       hasQuotas = true;
529       break;
530     }
531
532     if (hasQuotas) {
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;
541     }
542   }
543 }
544
545 function onMessageContextMenu(event) {
546   var menu = $('messageListMenu');
547   Event.observe(menu, "hideMenu", onMessageContextMenuHide);
548   popupMenu(event, "messageListMenu", this);
549
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;
556   this.select();
557 }
558
559 function onMessageContextMenuHide(event) {
560   var topNode = $('messageList');
561
562   if (topNode.menuSelectedEntry) {
563     topNode.menuSelectedEntry.deselect();
564     topNode.menuSelectedEntry = null;
565   }
566   if (topNode.menuSelectedRows) {
567     var nodes = topNode.menuSelectedRows;
568     for (var i = 0; i < nodes.length; i++)
569       nodes[i].select();
570     topNode.menuSelectedRows = null;
571   }
572 }
573
574 function onFolderMenuClick(event) {
575   var onhide, menuName;
576    
577   var menutype = this.parentNode.getAttribute("datatype");
578   if (menutype) {
579     if (menutype == "inbox") {
580       menuName = "inboxIconMenu";
581     } else if (menutype == "account") {
582       menuName = "accountIconMenu";
583     } else if (menutype == "trash") {
584       menuName = "trashIconMenu";
585     } else {
586       menuName = "mailboxIconMenu";
587     }
588   } else {
589     menuName = "mailboxIconMenu";
590   }
591
592   var menu = $(menuName);
593   Event.observe(menu, "hideMenu", onFolderMenuHide);
594   popupMenu(event, menuName, this.parentNode);
595
596   var topNode = $("mailboxTree");
597   if (topNode.selectedEntry)
598     topNode.selectedEntry.deselect();
599   if (topNode.menuSelectedEntry)
600     topNode.menuSelectedEntry.deselect();
601   topNode.menuSelectedEntry = this;
602   this.select();
603
604   preventDefault(event);
605 }
606
607 function onFolderMenuHide(event) {
608   var topNode = $("mailboxTree");
609
610   if (topNode.menuSelectedEntry) {
611     topNode.menuSelectedEntry.deselect();
612     topNode.menuSelectedEntry = null;
613   }
614   if (topNode.selectedEntry)
615     topNode.selectedEntry.select();
616 }
617
618 function deleteCachedMessage(messageId) {
619   var done = false;
620   var counter = 0;
621
622   while (counter < cachedMessages.length
623          && !done)
624     if (cachedMessages[counter]
625         && cachedMessages[counter]['idx'] == messageId) {
626       cachedMessages.splice(counter, 1);
627       done = true;
628     }
629     else
630       counter++;
631 }
632
633 function getCachedMessage(idx) {
634   var message = null;
635   var counter = 0;
636
637   while (counter < cachedMessages.length
638          && message == null)
639     if (cachedMessages[counter]
640         && cachedMessages[counter]['idx'] == currentMailbox + '/' + idx)
641       message = cachedMessages[counter];
642     else
643       counter++;
644
645   return message;
646 }
647
648 function storeCachedMessage(cachedMessage) {
649   var oldest = -1;
650   var timeOldest = -1;
651   var counter = 0;
652
653   if (cachedMessages.length < maxCachedMessages)
654     oldest = cachedMessages.length;
655   else {
656     while (cachedMessages[counter]) {
657       if (oldest == -1
658           || cachedMessages[counter]['time'] < timeOldest) {
659         oldest = counter;
660         timeOldest = cachedMessages[counter]['time'];
661       }
662       counter++;
663     }
664
665     if (oldest == -1)
666       oldest = 0;
667   }
668
669   cachedMessages[oldest] = cachedMessage;
670 }
671
672 function onMessageSelectionChange() {
673   var rows = this.getSelectedRowsId();
674
675   if (rows.length == 1) {
676     var idx = rows[0].substr(4);
677
678     if (currentMessages[currentMailbox] != idx) {
679       currentMessages[currentMailbox] = idx;
680       loadMessage(idx);
681     }
682   }
683 }
684
685 function loadMessage(idx) {
686   if (document.messageAjaxRequest) {
687     document.messageAjaxRequest.aborted = true;
688     document.messageAjaxRequest.abort();
689   }
690
691   var cachedMessage = getCachedMessage(idx);
692
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);
699   } else {
700     var div = $('messageContent');
701     div.update(cachedMessage['text']);
702     cachedMessage['time'] = (new Date()).getTime();
703     document.messageAjaxRequest = null;
704     configureLinksInMessage();
705     resizeMailContent();
706   }
707 }
708
709 function configureLinksInMessage() {
710   var messageDiv = $('messageContent');
711   var mailContentDiv = document.getElementsByClassName('mailer_mailcontent',
712                                                        messageDiv)[0];
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]));
723     }
724     else
725       Event.observe(anchors[i], "click",
726                     onMessageAnchorClick.bindAsEventListener(anchors[i]));
727
728   var editDraftButton = $("editDraftButton");
729   if (editDraftButton)
730     Event.observe(editDraftButton, "click",
731                   onMessageEditDraft.bindAsEventListener(editDraftButton));
732 }
733
734 function resizeMailContent() {
735   var headerTable = document.getElementsByClassName('mailer_fieldtable')[0];
736   var contentDiv = document.getElementsByClassName('mailer_mailcontent')[0];
737   
738   contentDiv.setStyle({ 'top': (Element.getHeight(headerTable) + headerTable.offsetTop) + 'px' });
739 }
740
741 function onMessageContentMenu(event) {
742   popupMenu(event, 'messageContentMenu', this);
743 }
744
745 function onMessageEditDraft(event) {
746   return openMessageWindowsForSelection("edit", true);
747 }
748
749 function onEmailAddressClick(event) {
750   popupMenu(event, 'addressMenu', this);
751 }
752
753 function onMessageAnchorClick(event) {
754   window.open(this.href);
755   preventDefault(event);
756 }
757
758 function messageCallback(http) {
759   var div = $('messageContent');
760
761   if (http.readyState == 4
762       && http.status == 200) {
763     document.messageAjaxRequest = null;
764     div.update(http.responseText);
765     configureLinksInMessage();
766     resizeMailContent();
767     
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);
775     }
776   }
777   else
778     log("messageCallback: problem during ajax request: " + http.status);
779 }
780
781 function processMailboxMenuAction(mailbox) {
782   var currentNode, upperNode;
783   var mailboxName;
784   var action;
785
786   mailboxName = mailbox.getAttribute('mailboxname');
787   currentNode = mailbox;
788   upperNode = null;
789
790   while (currentNode
791          && !currentNode.hasAttribute('mailboxaction'))
792     currentNode = currentNode.parentNode.parentNode.parentMenuItem;
793
794   if (currentNode)
795     {
796       action = currentNode.getAttribute('mailboxaction');
797       //       var rows  = collectSelectedRows();
798       //       var rString = rows.join(', ');
799       //       alert("performing '" + action + "' on " + rString
800       //             + " to " + mailboxName);
801     }
802 }
803
804 var rowSelectionCount = 0;
805
806 validateControls();
807
808 function showElement(e, shouldShow) {
809   e.style.display = shouldShow ? "" : "none";
810 }
811
812 function enableElement(e, shouldEnable) {
813   if(!e)
814     return;
815   if(shouldEnable) {
816     if(e.hasAttribute("disabled"))
817       e.removeAttribute("disabled");
818   }
819   else {
820     e.setAttribute("disabled", "1");
821   }
822 }
823
824 function validateControls() {
825   var e = $("moveto");
826   this.enableElement(e, rowSelectionCount > 0);
827 }
828
829 function moveTo(uri) {
830   alert("MoveTo: " + uri);
831 }
832
833 /* message menu entries */
834 function onMenuOpenMessage(event) {
835   return openMessageWindowsForSelection('popupview');
836 }
837
838 function onMenuReplyToSender(event) {
839   return openMessageWindowsForSelection('reply');
840 }
841
842 function onMenuReplyToAll(event) {
843   return openMessageWindowsForSelection('replyall');
844 }
845
846 function onMenuForwardMessage(event) {
847   return openMessageWindowsForSelection('forward');
848 }
849
850 function onMenuViewMessageSource(event) {
851   var messageList = $("messageList");
852   var rows = messageList.getSelectedRowsId();
853
854   if (rows.length > 0) {
855     var url = (ApplicationBaseURL + currentMailbox + "/"
856                + rows[0].substr(4) + "/viewsource");
857     openMailComposeWindow(url);
858   }
859
860   preventDefault(event);
861 }
862
863 /* contacts */
864 function newContactFromEmail(event) {
865   var mailto = document.menuTarget.innerHTML;
866
867   var email = extractEmailAddress(mailto);
868   var c_name = extractEmailName(mailto);
869   if (email.length > 0)
870     {
871       var url = UserFolderURL + "Contacts/new?contactEmail=" + email;
872       if (c_name)
873         url += "&contactFN=" + c_name;
874       openContactWindow(url);
875     }
876
877   return false; /* stop following the link */
878 }
879
880 function newEmailTo(sender) {
881   return openMailTo(document.menuTarget.innerHTML);
882 }
883
884 function expandUpperTree(node) {
885   var currentNode = node.parentNode;
886
887   while (currentNode.className != "dtree") {
888     if (currentNode.className == 'clip') {
889       var id = currentNode.getAttribute("id");
890       var number = parseInt(id.substr(2));
891       if (number > 0) {
892         var cn = mailboxTree.aNodes[number];
893         mailboxTree.nodeStatus(1, number, cn._ls);
894       }
895     }
896     currentNode = currentNode.parentNode;
897   }
898 }
899
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";
909   else
910     newSortAttribute = "arrival";
911
912   if (sorting["attribute"] == newSortAttribute)
913     sorting["ascending"] = !sorting["ascending"];
914   else {
915     sorting["attribute"] = newSortAttribute;
916     sorting["ascending"] = true;
917   }
918   refreshCurrentFolder();
919   
920   Event.stop(event);
921 }
922
923 function refreshCurrentFolder() {
924   openMailbox(currentMailbox, true);
925 }
926
927 function refreshFolderByType(type) {
928   if (currentMailboxType == type)
929     refreshCurrentFolder();
930 }
931
932 var mailboxSpanAcceptType = function(type) {
933   return (type == "mailRow");
934 }
935
936 var mailboxSpanEnter = function() {
937   this.addClassName("_dragOver");
938 }
939
940 var mailboxSpanExit = function() {
941   this.removeClassName("_dragOver");
942 }
943
944 var mailboxSpanDrop = function(data) {
945   var success = false;
946
947   if (data) {
948     var folder = this.parentNode.parentNode.getAttribute("dataname");
949     if (folder != currentMailbox)
950       success = (moveMessages(data, folder) == 0);
951   }
952   else
953     success = false;
954
955   return success;
956 }
957
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);
962 }
963
964 var plusSignExit = function() {
965   if (this.plusSignTimer) {
966     clearTimeout(this.plusSignTimer);
967     this.plusSignTimer = null;
968   }
969 }
970         
971 function openPlusSign(nodeNr) {
972   mailboxTree.nodeStatus(1, nodeNr, mailboxTree.aNodes[nodeNr]._ls);
973   mailboxTree.aNodes[nodeNr]._io = 1;
974   this.plusSignTimer = null;
975 }
976
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;
986
987   var newImg = document.createElement("img");
988   newImg.src = ResourcesURL + "/message-mail.png";
989
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..."));
995
996   return newDiv;
997 }
998
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));
1004
1005   return msgIds;
1006 }
1007
1008 /* a model for a futur refactoring of the sortable table headers mechanism */
1009 function configureMessageListEvents(table) {
1010   if (table) {
1011     table.multiselect = true;
1012     // Each body row can load a message
1013     Event.observe(table, "mousedown",
1014                   onMessageSelectionChange.bindAsEventListener(table));    
1015     // Sortable columns
1016     configureSortableTableHeaders(table);
1017   }
1018 }
1019
1020 function configureMessageListBodyEvents(table) {
1021   if (table) {
1022     // Page navigation
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]));
1028     }
1029
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]));
1035       
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]);
1040
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));
1046         else if (j == 4) {
1047           var img = cell.childNodesWithTag("img")[0];
1048           Event.observe(img, "click", mailListMarkMessage);
1049         }
1050       }
1051     }
1052   }
1053 }
1054
1055 function configureDragHandles() {
1056   var handle = $("verticalDragHandle");
1057   if (handle) {
1058     handle.addInterface(SOGoDragHandlesInterface);
1059     handle.leftMargin = 1;
1060     handle.leftBlock=$("leftPanel");
1061     handle.rightBlock=$("rightPanel");
1062   }
1063
1064   handle = $("rightDragHandle");
1065   if (handle) {
1066     handle.addInterface(SOGoDragHandlesInterface);
1067     handle.upperBlock=$("mailboxContent");
1068     handle.lowerBlock=$("messageContent");
1069   }
1070 }
1071
1072 /* dnd */
1073 function initDnd() {
1074   //   log("MailerUI initDnd");
1075
1076   var tree = $("mailboxTree");
1077   if (tree) {
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]);
1085       }
1086     }
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]);
1094     }
1095   }
1096 }
1097
1098 /* stub */
1099
1100 function refreshContacts() {
1101 }
1102
1103 function openInbox(node) {
1104   var done = false;
1105   openMailbox(node.parentNode.getAttribute("dataname"));
1106   var tree = $("mailboxTree");
1107   tree.selectedEntry = node;
1108   node.select();
1109   mailboxTree.o(1);
1110 }
1111
1112 function initMailer(event) {
1113   if (!document.body.hasClassName("popup")) {
1114 //     initDnd();
1115     initMailboxTree();
1116     initMessageCheckTimer();
1117   }
1118 }
1119
1120 function initMessageCheckTimer() {
1121   var messageCheck = userDefaults["MessageCheck"];
1122   if (messageCheck && messageCheck != "manually") {
1123     var interval;
1124     if (messageCheck == "once_per_hour")
1125       interval = 3600;
1126     else if (messageCheck == "every_minute")
1127       interval = 60;
1128     else {
1129       interval = parseInt(messageCheck.substr(6)) * 60;
1130     }
1131     messageCheckTimer = window.setInterval(onMessageCheckCallback,
1132                                            interval * 1000);
1133   }
1134 }
1135
1136 function onMessageCheckCallback(event) {
1137   refreshMailbox();
1138 }
1139
1140 function initMailboxTree() {
1141   mailboxTree = new dTree("mailboxTree");
1142   mailboxTree.config.folderLinks = true;
1143   mailboxTree.config.hideRoot = true;
1144
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";
1159
1160   mailboxTree.add(0, -1, '');
1161
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]);
1167   }
1168 }
1169
1170 function updateMailboxTreeInPage() {
1171   $("folderTreeContent").update(mailboxTree);
1172
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]));
1181     if (!inboxFound
1182         && nodes[i].parentNode.getAttribute("datatype") == "inbox") {
1183       openInbox(nodes[i]);
1184       inboxFound = true;
1185     }
1186   }
1187 }
1188
1189 function mailboxMenuNode(type, name) {
1190   var newNode = document.createElement("li");
1191   var icon = MailerUIdTreeExtension.folderIcons[type];
1192   if (!icon)
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];
1198   if (!displayName)
1199     displayName = name;
1200   newNode.appendChild(document.createTextNode(" " + displayName));
1201
1202   return newNode;
1203 }
1204
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);
1212
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("-");
1222   }
1223
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);
1233       submenuCount++;
1234     }
1235     else {
1236       newNode.mailbox = child;
1237       callbacks.push(callback);
1238     }
1239   }
1240   initMenu(menuDIV, callbacks);
1241
1242   return menuDIV.getAttribute("id");
1243 }
1244
1245 function updateMailboxMenus() {
1246   var mailboxActions = { move: onMailboxMenuMove,
1247                          copy: onMailboxMenuCopy };
1248
1249   for (key in mailboxActions) {
1250     var menuId = key + "MailboxMenu";
1251     var menuDIV = $(menuId);
1252     if (menuDIV)
1253       menuDIV.parentNode.removeChild(menuDIV);
1254
1255     menuDIV = document.createElement("div");
1256     pageContent = $("pageContent");
1257     pageContent.appendChild(menuDIV);
1258
1259     var menu = document.createElement("ul");
1260     menuDIV.appendChild(menu);
1261
1262     $(menuDIV).addClassName("menu");
1263     menuDIV.setAttribute("id", menuId);
1264
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);
1273     }
1274     initMenu(menuDIV, submenuIds);
1275   }
1276 }
1277
1278 function onLoadMailboxesCallback(http) {
1279   if (http.readyState == 4
1280       && http.status == 200) {
1281     checkAjaxRequestsState();
1282     var newAccount = buildMailboxes(http.callbackData,
1283                                     http.responseText);
1284     accounts[http.callbackData] = newAccount;
1285     mailboxTree.addMailAccount(newAccount);
1286     mailboxTree.pendingRequests--;
1287     activeAjaxRequests--;
1288     if (!mailboxTree.pendingRequests) {
1289       updateMailboxTreeInPage();
1290       updateMailboxMenus();
1291       checkAjaxRequestsState();
1292     }
1293   }
1294
1295   //       var tree = $("mailboxTree");
1296   //       var treeNodes = document.getElementsByClassName("dTreeNode", tree);
1297   //       var i = 0;
1298   //       while (i < treeNodes.length
1299   //         && treeNodes[i].getAttribute("dataname") != currentMailbox)
1300   //     i++;
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]);
1309   //       }
1310 }
1311
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]);
1320       if (!node) {
1321         node = new Mailbox("additional", names[j]);
1322         currentNode.addMailbox(node);
1323       }
1324       currentNode = node;
1325     }
1326     var basename = names[names.length-1];
1327     var leaf = currentNode.findMailboxByName(basename);
1328     if (leaf)
1329       leaf.type = data[i].type;
1330     else {
1331       leaf = new Mailbox(data[i].type, basename);
1332       currentNode.addMailbox(leaf);
1333     }
1334   }
1335
1336   return account;
1337 }
1338
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);
1345   }
1346 }
1347
1348 function onMenuRenameFolder(event) {
1349   var name = window.prompt(labels["Enter the new name of your folder :"]
1350                            ,
1351                            "");
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);
1356   }
1357 }
1358
1359 function onMenuDeleteFolder(event) {
1360   var answer = window.confirm(labels["Do you really want to move this folder into the trash ?"]);
1361   if (answer) {
1362     var folderID = document.menuTarget.getAttribute("dataname");
1363     var urlstr = URLForFolderID(folderID) + "/deleteFolder";
1364     triggerAjaxRequest(urlstr, folderOperationCallback);
1365   }
1366 }
1367
1368 function onMenuExpungeFolder(event) {
1369   var folderID = document.menuTarget.getAttribute("dataname");
1370   var urlstr = URLForFolderID(folderID) + "/expunge";
1371   triggerAjaxRequest(urlstr, folderRefreshCallback, folderID);
1372 }
1373
1374 function onMenuEmptyTrash(event) {
1375   var folderID = document.menuTarget.getAttribute("dataname");
1376   var urlstr = URLForFolderID(folderID) + "/emptyTrash";
1377   triggerAjaxRequest(urlstr, folderOperationCallback, folderID);
1378
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();
1384   }
1385   var msgID = currentMessages[folderID];
1386   if (msgID)
1387     deleteCachedMessage(folderID + "/" + msgID);
1388 }
1389
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!"]);
1394   else {
1395     var folderID = document.menuTarget.getAttribute("dataname");
1396     var urlstr = URLForFolderID(folderID) + "/setAs" + folder + "Folder";
1397     triggerAjaxRequest(urlstr, folderOperationCallback);
1398   }
1399 }
1400
1401 function onMenuChangeToDraftsFolder(event) {
1402   return _onMenuChangeToXXXFolder(event, "Drafts");
1403 }
1404
1405 function onMenuChangeToSentFolder(event) {
1406   return _onMenuChangeToXXXFolder(event, "Sent");
1407 }
1408
1409 function onMenuChangeToTrashFolder(event) {
1410   return _onMenuChangeToXXXFolder(event, "Trash");
1411 }
1412
1413 function onMenuLabelNone() {
1414   var rowId = document.menuTarget.getAttribute("id").substr(4);
1415   var messageId = currentMailbox + "/" + rowId;
1416   var urlstr = ApplicationBaseURL + messageId + "/removeAllLabels";
1417   triggerAjaxRequest(urlstr, messageFlagCallback,
1418                      { mailbox: currentMailbox, msg: rowId, label: null } );
1419 }
1420
1421 function _onMenuLabelFlagX(flag) {
1422   var flags = document.menuTarget.getAttribute("labels").split(" ");
1423
1424   var rowId = document.menuTarget.getAttribute("id").substr(4);
1425   var messageId = currentMailbox + "/" + rowId;
1426
1427   var operation = "add";
1428   if (flags.indexOf("label" + flag) > -1)
1429     operation = "remove";
1430   var urlstr = (ApplicationBaseURL + messageId
1431                 + "/" + operation + "Label" + flag);
1432   triggerAjaxRequest(urlstr, messageFlagCallback,
1433                      { mailbox: currentMailbox, msg: rowId,
1434                        label: operation + flag } );
1435 }
1436
1437 function onMenuLabelFlag1() {
1438   _onMenuLabelFlagX(1);
1439 }
1440
1441 function onMenuLabelFlag2() {
1442   _onMenuLabelFlagX(2);
1443 }
1444
1445 function onMenuLabelFlag3() {
1446   _onMenuLabelFlagX(3);
1447 }
1448
1449 function onMenuLabelFlag4() {
1450   _onMenuLabelFlagX(4);
1451 }
1452
1453 function onMenuLabelFlag5() {
1454   _onMenuLabelFlagX(5);
1455 }
1456
1457 function folderOperationCallback(http) {
1458   if (http.readyState == 4
1459       && isHttpStatus204(http.status))
1460     initMailboxTree();
1461   else
1462     window.alert(labels["Operation failed"]);
1463 }
1464
1465 function folderRefreshCallback(http) {
1466   if (http.readyState == 4
1467       && isHttpStatus204(http.status)) {
1468     var oldMailbox = http.callbackData;
1469     if (oldMailbox == currentMailbox)
1470       refreshCurrentFolder();
1471   }
1472   else
1473     window.alert(labels["Operation failed"]);
1474 }
1475
1476 function messageFlagCallback(http) {
1477   if (http.readyState == 4
1478       && isHttpStatus204(http.status)) {
1479     var data = http.callbackData;
1480     if (data["mailbox"] == currentMailbox) {
1481       var row = $("row_" + data["msg"]);
1482       var operation = data["label"];
1483       if (operation) {
1484         var labels = row.getAttribute("labels");
1485         var flags;
1486         if (labels.length > 0)
1487           flags = labels.split(" ");
1488         else
1489           flags = new Array();
1490         if (operation.substr(0, 3) == "add")
1491           flags.push("label" + operation.substr(3));
1492         else {
1493           var flag = "label" + operation.substr(6);
1494           var idx = flags.indexOf(flag);
1495           flags.splice(idx, 1);
1496         }
1497         row.setAttribute("labels", flags.join(" "));
1498       }
1499       else
1500         row.setAttribute("labels", "");
1501     }
1502   }
1503 }
1504
1505 function onLabelMenuPrepareVisibility() {
1506   var messageList = $("messageList");
1507   var flags = {};
1508
1509   if (messageList) {
1510     var rows = messageList.getSelectedRows();
1511     for (var i = 0; i < rows.length; i++) {
1512       $w(rows[i].getAttribute("labels")).each(function(flag) {
1513         flags[flag] = true;
1514         });
1515     }
1516   }
1517
1518   var lis = this.childNodesWithTag("ul")[0].childNodesWithTag("li")
1519   var isFlagged = false;
1520   for (var i = 1; i < 6; i++) {
1521     if (flags["label" + i]) {
1522       isFlagged = true;
1523       lis[1 + i].addClassName("_chosen");
1524     }
1525     else
1526       lis[1 + i].removeClassName("_chosen");
1527   }
1528   if (isFlagged)
1529     lis[0].removeClassName("_chosen");
1530   else
1531     lis[0].addClassName("_chosen");
1532 }
1533
1534 function getMenus() {
1535   var menus = {}
1536   menus["accountIconMenu"] = new Array(null, null, onMenuCreateFolder, null,
1537                                        null, null);
1538   menus["inboxIconMenu"] = new Array(null, null, null, "-", null,
1539                                      onMenuCreateFolder, onMenuExpungeFolder,
1540                                      "-", null,
1541                                      onMenuSharing);
1542   menus["trashIconMenu"] = new Array(null, null, null, "-", null,
1543                                      onMenuCreateFolder, onMenuExpungeFolder,
1544                                      onMenuEmptyTrash, "-", null,
1545                                      onMenuSharing);
1546   menus["mailboxIconMenu"] = new Array(null, null, null, "-", null,
1547                                        onMenuCreateFolder,
1548                                        onMenuRenameFolder,
1549                                        onMenuExpungeFolder,
1550                                        onMenuDeleteFolder,
1551                                        "folderTypeMenu",
1552                                        "-", null,
1553                                        onMenuSharing);
1554   menus["addressMenu"] = new Array(newContactFromEmail, newEmailTo, null);
1555   menus["messageListMenu"] = new Array(onMenuOpenMessage, "-",
1556                                        onMenuReplyToSender,
1557                                        onMenuReplyToAll,
1558                                        onMenuForwardMessage, null,
1559                                        "-", "moveMailboxMenu",
1560                                        "copyMailboxMenu", "label-menu",
1561                                        "mark-menu", "-", null,
1562                                        onMenuViewMessageSource, null,
1563                                        null, onMenuDeleteMessage);
1564   menus["messageContentMenu"] = new Array(onMenuReplyToSender,
1565                                           onMenuReplyToAll,
1566                                           onMenuForwardMessage,
1567                                           null, "moveMailboxMenu",
1568                                           "copyMailboxMenu",
1569                                           "-", "label-menu", "mark-menu",
1570                                           "-",
1571                                           null, onMenuViewMessageSource,
1572                                           null, onPrintCurrentMessage,
1573                                           onMenuDeleteMessage);
1574   menus["folderTypeMenu"] = new Array(onMenuChangeToSentFolder,
1575                                       onMenuChangeToDraftsFolder,
1576                                       onMenuChangeToTrashFolder);
1577
1578   menus["label-menu"] = new Array(onMenuLabelNone, "-", onMenuLabelFlag1,
1579                                   onMenuLabelFlag2, onMenuLabelFlag3,
1580                                   onMenuLabelFlag4, onMenuLabelFlag5);
1581   menus["mark-menu"] = new Array(null, null, null, null, "-", null, "-",
1582                                  null, null, null);
1583   menus["searchMenu"] = new Array(setSearchCriteria, setSearchCriteria,
1584                                   setSearchCriteria, setSearchCriteria,
1585                                   setSearchCriteria);
1586   var labelMenu = $("label-menu");
1587   if (labelMenu)
1588     labelMenu.prepareVisibility = onLabelMenuPrepareVisibility;
1589
1590   return menus;
1591 }
1592
1593 addEvent(window, 'load', initMailer);
1594
1595 function Mailbox(type, name) {
1596   this.type = type;
1597   this.name = name;
1598   this.parentFolder = null;
1599   this.children = new Array();
1600   return this;
1601 }
1602
1603 Mailbox.prototype.dump = function(indent) {
1604   if (!indent)
1605     indent = 0;
1606   log(" ".repeat(indent) + this.name);
1607   for (var i = 0; i < this.children.length; i++) {
1608     this.children[i].dump(indent + 2);
1609   }
1610 }
1611
1612 Mailbox.prototype.fullName = function() {
1613   var fullName = "";
1614
1615   var currentFolder = this;
1616   while (currentFolder.parentFolder) {
1617     fullName = "/folder" + currentFolder.name + fullName;
1618     currentFolder = currentFolder.parentFolder;
1619   }
1620
1621   return "/" + currentFolder.name + fullName;
1622 }
1623
1624 Mailbox.prototype.findMailboxByName = function(name) {
1625   var mailbox = null;
1626
1627   var i = 0;
1628   while (!mailbox && i < this.children.length)
1629     if (this.children[i].name == name)
1630       mailbox = this.children[i];
1631     else
1632       i++;
1633
1634   return mailbox;
1635 }
1636
1637 Mailbox.prototype.addMailbox = function(mailbox) {
1638   mailbox.parentFolder = this;
1639   this.children.push(mailbox);
1640 }