]> err.no Git - scalable-opengroupware.org/blob - UI/WebServerResources/MailerUI.js
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1194 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 /* mail list */
20
21 function openMessageWindow(msguid, url) {
22   var wId = '';
23   if (msguid) {
24     wId += "SOGo_msg_" + msguid;
25     markMailReadInWindow(window, msguid);
26   }
27   var msgWin = openMailComposeWindow(url, wId);
28   if (msguid) {
29     msgWin.messageId = msguid;
30     msgWin.messageURL = ApplicationBaseURL + currentMailbox + "/" + msguid;
31   }
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   if (type == "additional")
70     window.alert(clabels["The user rights cannot be"
71                          + " edited for this object!"]);
72   else {
73     var urlstr = URLForFolderID(folderID) + "/acls";
74     openAclWindow(urlstr);
75   }
76 }
77
78 /* mail list DOM changes */
79
80 function markMailInWindow(win, msguid, markread) {
81   var msgDiv;
82
83   msgDiv = win.$("div_" + msguid);
84   if (msgDiv) {
85     if (markread) {
86       msgDiv.removeClassName("mailer_unreadmailsubject");
87       msgDiv.addClassName("mailer_readmailsubject");
88       msgDiv = win.$("unreaddiv_" + msguid);
89       if (msgDiv)
90         {
91           msgDiv.setAttribute("class", "mailerUnreadIcon");
92           msgDiv.setAttribute("id", "readdiv_" + msguid);
93           msgDiv.setAttribute("src", ResourcesURL + "/icon_read.gif");
94           msgDiv.setAttribute("onclick", "mailListMarkMessage(this,"
95                               + " 'markMessageUnread', " + msguid
96                               + ", false);"
97                               +" return false;");
98           var title = msgDiv.getAttribute("title-markunread");
99           if (title)
100             msgDiv.setAttribute("title", title);
101         }
102     }
103     else {
104       msgDiv.removeClassName('mailer_readmailsubject');
105       msgDiv.addClassName('mailer_unreadmailsubject');
106       msgDiv = win.$("readdiv_" + msguid);
107       if (msgDiv)
108         {
109           msgDiv.setAttribute("class", "mailerReadIcon");
110           msgDiv.setAttribute("id", "unreaddiv_" + msguid);
111           msgDiv.setAttribute("src", ResourcesURL + "/icon_unread.gif");
112           msgDiv.setAttribute("onclick", "mailListMarkMessage(this,"
113                               + " 'markMessageRead', " + msguid
114                               + ", true);"
115                               +" return false;");
116           var title = msgDiv.getAttribute("title-markread");
117           if (title)
118             msgDiv.setAttribute("title", title);
119         }
120     }
121     return true;
122   }
123   else
124     return false;
125 }
126
127 function markMailReadInWindow(win, msguid) {
128   /* this is called by UIxMailView with window.opener */
129   return markMailInWindow(win, msguid, true);
130 }
131
132 /* mail list reply */
133
134 function openMessageWindowsForSelection(action, firstOnly) {
135   if (document.body.hasClassName("popup"))
136     win = openMessageWindow(window.messageId,
137                             window.messageURL + "/" + action);
138   else {
139     var messageList = $("messageList");
140     var rows = messageList.getSelectedRowsId();
141     if (rows.length > 0) {
142       if (firstOnly)
143         openMessageWindow(rows[0].substr(4),
144                           ApplicationBaseURL + currentMailbox
145                           + "/" + rows[0].substr(4)
146                           + "/" + action);
147       else
148         for (var i = 0; i < rows.length; i++)
149           openMessageWindow(rows[i].substr(4),
150                             ApplicationBaseURL + currentMailbox
151                             + "/" + rows[i].substr(4)
152                             + "/" + action);
153     } else {
154       window.alert(labels["Please select a message."]);
155     }
156   }
157
158   return false;
159 }
160
161 function mailListMarkMessage(event) {
162   var http = createHTTPClient();
163   var url = ApplicationBaseURL + currentMailbox + "/" + msguid + "/" + action;
164
165   if (http) {
166     // TODO: add parameter to signal that we are only interested in OK
167     http.open("POST", url, false /* not async */);
168     http.send("");
169     if (http.status != 200) {
170       // TODO: refresh page?
171       alert("Message Mark Failed: " + http.statusText);
172       window.location.reload();
173     }
174     else {
175       markMailInWindow(window, msguid, markread);
176     }
177   }
178   else {
179     window.location.href = url;
180   }
181 }
182
183 /* maillist row highlight */
184
185 var oldMaillistHighlight = null; // to remember deleted/selected style
186
187 function ml_highlight(sender) {
188   oldMaillistHighlight = sender.className;
189   if (oldMaillistHighlight == "tableview_highlight")
190     oldMaillistHighlight = null;
191   sender.className = "tableview_highlight";
192 }
193
194 function ml_lowlight(sender) {
195   if (oldMaillistHighlight) {
196     sender.className = oldMaillistHighlight;
197     oldMaillistHighlight = null;
198   }
199   else
200     sender.className = "tableview";
201 }
202
203
204 /* bulk delete of messages */
205
206 function uixDeleteSelectedMessages(sender) {
207   var failCount = 0;
208    
209   var messageList = $("messageList");
210   var rowIds = messageList.getSelectedRowsId();
211
212   for (var i = 0; i < rowIds.length; i++) {
213     var url, http;
214     var rowId = rowIds[i].substr(4);
215     /* send AJAX request (synchronously) */
216
217     var messageId = currentMailbox + "/" + rowId;
218     url = ApplicationBaseURL + messageId + "/trash";
219     http = createHTTPClient();
220     http.open("POST", url, false /* not async */);
221     http.url = url;
222     http.send("");
223     if (!isHttpStatus204(http.status)) { /* request failed */
224       failCount++;
225       http = null;
226       continue;
227     } else {
228       deleteCachedMessage(messageId);
229       if (currentMessages[currentMailbox] == rowId) {
230         var div = $('messageContent');
231         div.update();
232         currentMessages[currentMailbox] = null;
233       }
234     }
235     http = null;
236     
237     /* remove from page */
238     /* line-through would be nicer, but hiding is OK too */
239     var row = $(rowIds[i]);
240     row.parentNode.removeChild(row);
241   }
242
243   if (failCount > 0)
244     alert("Could not delete " + failCount + " messages!");
245    
246   return false;
247 }
248
249 function moveMessages(rowIds, folder) {
250   var failCount = 0;
251
252   for (var i = 0; i < rowIds.length; i++) {
253     var url, http;
254
255     /* send AJAX request (synchronously) */
256           
257     var messageId = currentMailbox + "/" + rowIds[i];
258     url = (ApplicationBaseURL + messageId
259            + "/move?tofolder=" + folder);
260     http = createHTTPClient();
261     http.open("GET", url, false /* not async */);
262     http.send("");
263     if (http.status == 200) {
264       var row = $("row_" + rowIds[i]);
265       row.parentNode.removeChild(row);
266       deleteCachedMessage(messageId);
267       if (currentMessages[currentMailbox] == rowIds[i]) {
268         var div = $('messageContent');
269         div.update();
270         currentMessages[currentMailbox] = null;
271       }
272     }
273     else /* request failed */
274       failCount++;
275
276     /* remove from page */
277
278     /* line-through would be nicer, but hiding is OK too */
279   }
280
281   if (failCount > 0)
282     alert("Could not move " + failCount + " messages!");
283    
284   return failCount;
285 }
286
287 function onMenuDeleteMessage(event) {
288   uixDeleteSelectedMessages();
289   preventDefault(event);
290 }
291
292 function onPrintCurrentMessage(event) {
293   var rowIds = $("messageList").getSelectedRowsId();
294   if (rowIds.length == 0) {
295     window.alert(labels["Please select a message to print."]);
296   }
297   else if (rowIds.length > 1) {
298     window.alert(labels["Please select only one message to print."]);
299   }
300   else
301     window.print();
302
303   preventDefault(event);
304 }
305
306 function onMailboxTreeItemClick(event) {
307   var topNode = $("mailboxTree");
308   var mailbox = this.parentNode.getAttribute("dataname");
309
310   if (topNode.selectedEntry)
311     topNode.selectedEntry.deselect();
312   this.select();
313   topNode.selectedEntry = this;
314
315   search = {};
316   sorting = {};
317   $("searchValue").value = "";
318   initCriteria();
319
320   currentMailboxType = this.parentNode.getAttribute("datatype");
321   if (currentMailboxType == "account" || currentMailboxType == "additional") {
322     currentMailbox = mailbox;
323     $("messageContent").update();
324     var table = $("messageList");
325     var head = table.tHead;
326     var body = table.tBodies[0];
327     for (var i = body.rows.length; i > 0; i--)
328       body.deleteRow(i-1);
329     if (head.rows[1])
330       head.rows[1].firstChild.update();
331   }
332   else
333     openMailbox(mailbox);
334    
335   Event.stop(event);
336 }
337
338 function _onMailboxMenuAction(menuEntry, error, actionName) {
339   var targetMailbox = menuEntry.mailbox.fullName();
340
341   if (targetMailbox == currentMailbox)
342     window.alert(labels[error]);
343   else {
344     var message;
345     if (document.menuTarget.tagName == "DIV")
346       message = currentMessages[currentMailbox];
347     else
348       message = document.menuTarget.getAttribute("id").substr(4);
349
350     var urlstr = (URLForFolderID(currentMailbox) + "/" + message
351                   + "/" + actionName + "?folder=" + targetMailbox);
352     triggerAjaxRequest(urlstr, folderRefreshCallback, currentMailbox);
353   }
354 }
355
356 function onMailboxMenuMove(event) {
357   _onMailboxMenuAction(this,
358                        "Moving a message into its own folder is impossible!",
359                        "move");
360 }
361
362 function onMailboxMenuCopy(event) {
363   _onMailboxMenuAction(this,
364                        "Copying a message into its own folder is impossible!",
365                        "copy");
366 }
367
368 function refreshMailbox() {
369   var topWindow = getTopWindow();
370   if (topWindow)
371     topWindow.refreshCurrentFolder();
372
373   return false;
374 }
375
376 function onComposeMessage() {
377   var topWindow = getTopWindow();
378   if (topWindow)
379     topWindow.composeNewMessage();
380
381   return false;
382 }
383
384 function composeNewMessage() {
385   var account = currentMailbox.split("/")[1];
386   var url = ApplicationBaseURL + "/" + account + "/compose";
387   openMailComposeWindow(url);
388 }
389
390 function openMailbox(mailbox, reload, idx) {
391   if (mailbox != currentMailbox || reload) {
392     currentMailbox = mailbox;
393     var url = ApplicationBaseURL + encodeURI(mailbox) + "/view?noframe=1";
394     var messageContent = $("messageContent");
395     messageContent.update();
396     lastClickedRow = null; // from generic.js
397
398     var currentMessage;
399     if (!idx) {
400       currentMessage = currentMessages[mailbox];
401       if (currentMessage) {
402         loadMessage(currentMessage);
403         url += '&pageforuid=' + currentMessage;
404       }
405     }
406
407     var searchValue = search["value"];
408     if (searchValue && searchValue.length > 0)
409       url += ("&search=" + search["criteria"]
410               + "&value=" + escape(searchValue));
411     var sortAttribute = sorting["attribute"];
412     if (sortAttribute && sortAttribute.length > 0)
413       url += ("&sort=" + sorting["attribute"]
414               + "&asc=" + sorting["ascending"]);
415     if (idx)
416       url += "&idx=" + idx;
417     if (document.messageListAjaxRequest) {
418       document.messageListAjaxRequest.aborted = true;
419       document.messageListAjaxRequest.abort();
420     }
421
422     var mailboxContent = $("mailboxContent");
423     if (mailboxContent.getStyle('visibility') == "hidden") {
424       mailboxContent.setStyle({ visibility: "visible" });
425       var rightDragHandle = $("rightDragHandle");
426       rightDragHandle.setStyle({ visibility: "visible" });
427       messageContent.setStyle({ top: (rightDragHandle.offsetTop
428                                       + rightDragHandle.offsetHeight
429                                       + 'px') });
430     }
431     document.messageListAjaxRequest
432       = triggerAjaxRequest(url, messageListCallback,
433                            currentMessage);
434
435     var quotasUrl = ApplicationBaseURL + mailbox + "/quotas";
436     document.quotasAjaxRequest
437       = triggerAjaxRequest(quotasUrl, quotasCallback);
438   }
439 }
440
441 function openMailboxAtIndex(event) {
442   openMailbox(currentMailbox, true, this.getAttribute("idx"));
443
444   Event.stop(event);
445 }
446
447 function messageListCallback(http) {
448   var div = $('mailboxContent');
449   var table = $('messageList');
450   
451   if (http.readyState == 4
452       && http.status == 200) {
453     document.messageListAjaxRequest = null;    
454
455     if (table) {
456       // Update table
457       var thead = table.tHead;
458       var tbody = table.tBodies[0];
459       var tmp = document.createElement('div');
460       $(tmp).update(http.responseText);
461       thead.rows[1].parentNode.replaceChild(tmp.firstChild.tHead.rows[1], thead.rows[1]);
462       table.replaceChild(tmp.firstChild.tBodies[0], tbody);
463     }
464     else {
465       // Add table
466       div.update(http.responseText);
467       table = $('messageList');
468       configureMessageListEvents(table);
469       TableKit.Resizable.init(table, {'trueResize' : true, 'keepWidth' : true});
470     }
471     configureMessageListBodyEvents(table);
472
473     var selected = http.callbackData;
474     if (selected) {
475       var row = $("row_" + selected);
476       if (row) {
477         row.select();
478         div.scrollTop = row.rowIndex * row.getHeight(); // scroll to selected message
479       }
480       else
481         $("messageContent").update();
482     }
483     else
484       div.scrollTop = 0;
485     
486     if (sorting["attribute"] && sorting["attribute"].length > 0) {
487       var sortHeader = $(sorting["attribute"] + "Header");
488       
489       if (sortHeader) {
490         var sortImages = $(table.tHead).getElementsByClassName("sortImage");
491         $(sortImages).each(function(item) {
492             item.remove();
493           });
494
495         var sortImage = createElement("img", "messageSortImage", "sortImage");
496         sortHeader.insertBefore(sortImage, sortHeader.firstChild);
497         if (sorting["ascending"])
498           sortImage.src = ResourcesURL + "/title_sortdown_12x12.png";
499         else
500           sortImage.src = ResourcesURL + "/title_sortup_12x12.png";
501       }
502     }
503   }
504   else {
505     var data = http.responseText;
506     var msg = data.replace(/^(.*\n)*.*<p>((.*\n)*.*)<\/p>(.*\n)*.*$/, "$2");
507     log("messageListCallback: problem during ajax request (readyState = " + http.readyState + ", status = " + http.status + ", response = " + msg + ")");
508   }
509 }
510
511 function quotasCallback(http) {
512   if (http.readyState == 4
513       && http.status == 200) {
514     var hasQuotas = false;
515
516     var quotas = http.responseText.evalJSON(true);
517     for (var i in quotas) {
518       hasQuotas = true;
519       break;
520     }
521
522     if (hasQuotas) {
523       var treePath = currentMailbox.split("/");
524       var mbQuotas = quotas["/" + treePath[2]];
525       var used = mbQuotas["usedSpace"];
526       var max = mbQuotas["maxQuota"];
527       var percents = (Math.round(used * 10000 / max) / 100);
528       var format = labels["quotasFormat"];
529       var text = format.formatted(used, max, percents);
530       window.status = text;
531     }
532   }
533 }
534
535 function onMessageContextMenu(event) {
536   var menu = $('messageListMenu');
537   Event.observe(menu, "hideMenu", onMessageContextMenuHide);
538   popupMenu(event, "messageListMenu", this);
539
540   var topNode = $('messageList');
541   var selectedNodes = topNode.getSelectedRows();
542   for (var i = 0; i < selectedNodes.length; i++)
543     selectedNodes[i].deselect();
544   topNode.menuSelectedRows = selectedNodes;
545   topNode.menuSelectedEntry = this;
546   this.select();
547 }
548
549 function onMessageContextMenuHide(event) {
550   var topNode = $('messageList');
551
552   if (topNode.menuSelectedEntry) {
553     topNode.menuSelectedEntry.deselect();
554     topNode.menuSelectedEntry = null;
555   }
556   if (topNode.menuSelectedRows) {
557     var nodes = topNode.menuSelectedRows;
558     for (var i = 0; i < nodes.length; i++)
559       nodes[i].select();
560     topNode.menuSelectedRows = null;
561   }
562 }
563
564 function onFolderMenuClick(event) {
565   var onhide, menuName;
566    
567   var menutype = this.parentNode.getAttribute("datatype");
568   if (menutype) {
569     if (menutype == "inbox") {
570       menuName = "inboxIconMenu";
571     } else if (menutype == "account") {
572       menuName = "accountIconMenu";
573     } else if (menutype == "trash") {
574       menuName = "trashIconMenu";
575     } else {
576       menuName = "mailboxIconMenu";
577     }
578   } else {
579     menuName = "mailboxIconMenu";
580   }
581
582   var menu = $(menuName);
583   Event.observe(menu, "hideMenu", onFolderMenuHide);
584   popupMenu(event, menuName, this.parentNode);
585
586   var topNode = $("mailboxTree");
587   if (topNode.selectedEntry)
588     topNode.selectedEntry.deselect();
589   if (topNode.menuSelectedEntry)
590     topNode.menuSelectedEntry.deselect();
591   topNode.menuSelectedEntry = this;
592   this.select();
593
594   preventDefault(event);
595 }
596
597 function onFolderMenuHide(event) {
598   var topNode = $("mailboxTree");
599
600   if (topNode.menuSelectedEntry) {
601     topNode.menuSelectedEntry.deselect();
602     topNode.menuSelectedEntry = null;
603   }
604   if (topNode.selectedEntry)
605     topNode.selectedEntry.select();
606 }
607
608 function deleteCachedMessage(messageId) {
609   var done = false;
610   var counter = 0;
611
612   while (counter < cachedMessages.length
613          && !done)
614     if (cachedMessages[counter]
615         && cachedMessages[counter]['idx'] == messageId) {
616       cachedMessages.splice(counter, 1);
617       done = true;
618     }
619     else
620       counter++;
621 }
622
623 function getCachedMessage(idx) {
624   var message = null;
625   var counter = 0;
626
627   while (counter < cachedMessages.length
628          && message == null)
629     if (cachedMessages[counter]
630         && cachedMessages[counter]['idx'] == currentMailbox + '/' + idx)
631       message = cachedMessages[counter];
632     else
633       counter++;
634
635   return message;
636 }
637
638 function storeCachedMessage(cachedMessage) {
639   var oldest = -1;
640   var timeOldest = -1;
641   var counter = 0;
642
643   if (cachedMessages.length < maxCachedMessages)
644     oldest = cachedMessages.length;
645   else {
646     while (cachedMessages[counter]) {
647       if (oldest == -1
648           || cachedMessages[counter]['time'] < timeOldest) {
649         oldest = counter;
650         timeOldest = cachedMessages[counter]['time'];
651       }
652       counter++;
653     }
654
655     if (oldest == -1)
656       oldest = 0;
657   }
658
659   cachedMessages[oldest] = cachedMessage;
660 }
661
662 function onMessageSelectionChange() {
663   var rows = this.getSelectedRowsId();
664
665   if (rows.length == 1) {
666     var idx = rows[0].substr(4);
667
668     if (currentMessages[currentMailbox] != idx) {
669       currentMessages[currentMailbox] = idx;
670       loadMessage(idx);
671     }
672   }
673 }
674
675 function loadMessage(idx) {
676   if (document.messageAjaxRequest) {
677     document.messageAjaxRequest.aborted = true;
678     document.messageAjaxRequest.abort();
679   }
680
681   var cachedMessage = getCachedMessage(idx);
682
683   if (cachedMessage == null) {
684     var url = (ApplicationBaseURL + currentMailbox + "/"
685                + idx + "/view?noframe=1");
686     document.messageAjaxRequest
687       = triggerAjaxRequest(url, messageCallback, idx);
688     markMailInWindow(window, idx, true);
689   } else {
690     var div = $('messageContent');
691     div.update(cachedMessage['text']);
692     cachedMessage['time'] = (new Date()).getTime();
693     document.messageAjaxRequest = null;
694     configureLinksInMessage();
695   }
696 }
697
698 function configureLinksInMessage() {
699   var messageDiv = $('messageContent');
700   var mailContentDiv = document.getElementsByClassName('mailer_mailcontent',
701                                                        messageDiv)[0];
702   Event.observe(mailContentDiv, "contextmenu",
703                 onMessageContentMenu.bindAsEventListener(mailContentDiv));
704   var anchors = messageDiv.getElementsByTagName('a');
705   for (var i = 0; i < anchors.length; i++)
706     if (anchors[i].href.substring(0,7) == "mailto:") {
707       Event.observe(anchors[i], "click",
708                     onEmailAddressClick.bindAsEventListener(anchors[i]));
709       Event.observe(anchors[i], "contextmenu",
710                     onEmailAddressClick.bindAsEventListener(anchors[i]));
711     }
712     else
713       Event.observe(anchors[i], "click",
714                     onMessageAnchorClick);
715
716   var editDraftButton = $("editDraftButton");
717   if (editDraftButton)
718     Event.observe(editDraftButton, "click", onMessageEditDraft);
719 }
720
721 function onMessageContentMenu(event) {
722   popupMenu(event, 'messageContentMenu', this);
723 }
724
725 function onMessageEditDraft(event) {
726   return openMessageWindowsForSelection("edit", true);
727 }
728
729 function onEmailAddressClick(event) {
730   popupMenu(event, 'addressMenu', this);
731 }
732
733 function onMessageAnchorClick (event) {
734   window.open(this.href);
735   preventDefault(event);
736 }
737
738 function messageCallback(http) {
739   var div = $('messageContent');
740
741   if (http.readyState == 4
742       && http.status == 200) {
743     document.messageAjaxRequest = null;
744     div.update(http.responseText);
745     configureLinksInMessage();
746       
747     if (http.callbackData) {
748       var cachedMessage = new Array();
749       cachedMessage['idx'] = currentMailbox + '/' + http.callbackData;
750       cachedMessage['time'] = (new Date()).getTime();
751       cachedMessage['text'] = http.responseText;
752       if (cachedMessage['text'].length < 30000)
753         storeCachedMessage(cachedMessage);
754     }
755   }
756   else
757     log("messageCallback: problem during ajax request: " + http.status);
758 }
759
760 function processMailboxMenuAction(mailbox) {
761   var currentNode, upperNode;
762   var mailboxName;
763   var action;
764
765   mailboxName = mailbox.getAttribute('mailboxname');
766   currentNode = mailbox;
767   upperNode = null;
768
769   while (currentNode
770          && !currentNode.hasAttribute('mailboxaction'))
771     currentNode = currentNode.parentNode.parentNode.parentMenuItem;
772
773   if (currentNode)
774     {
775       action = currentNode.getAttribute('mailboxaction');
776       //       var rows  = collectSelectedRows();
777       //       var rString = rows.join(', ');
778       //       alert("performing '" + action + "' on " + rString
779       //             + " to " + mailboxName);
780     }
781 }
782
783 var rowSelectionCount = 0;
784
785 validateControls();
786
787 function showElement(e, shouldShow) {
788   e.style.display = shouldShow ? "" : "none";
789 }
790
791 function enableElement(e, shouldEnable) {
792   if(!e)
793     return;
794   if(shouldEnable) {
795     if(e.hasAttribute("disabled"))
796       e.removeAttribute("disabled");
797   }
798   else {
799     e.setAttribute("disabled", "1");
800   }
801 }
802
803 function validateControls() {
804   var e = $("moveto");
805   this.enableElement(e, rowSelectionCount > 0);
806 }
807
808 function moveTo(uri) {
809   alert("MoveTo: " + uri);
810 }
811
812 function deleteSelectedMails() {
813 }
814
815 /* message menu entries */
816 function onMenuOpenMessage(event) {
817   return openMessageWindowsForSelection('popupview');
818 }
819
820 function onMenuReplyToSender(event) {
821   return openMessageWindowsForSelection('reply');
822 }
823
824 function onMenuReplyToAll(event) {
825   return openMessageWindowsForSelection('replyall');
826 }
827
828 function onMenuForwardMessage(event) {
829   return openMessageWindowsForSelection('forward');
830 }
831
832 function onMenuViewMessageSource(event) {
833   var messageList = $("messageList");
834   var rows = messageList.getSelectedRowsId();
835
836   if (rows.length > 0) {
837     var url = (ApplicationBaseURL + currentMailbox + "/"
838                + rows[0].substr(4) + "/viewsource");
839     openMailComposeWindow(url);
840   }
841
842   preventDefault(event);
843 }
844
845 /* contacts */
846 function newContactFromEmail(event) {
847   var mailto = document.menuTarget.innerHTML;
848
849   var email = extractEmailAddress(mailto);
850   var c_name = extractEmailName(mailto);
851   if (email.length > 0)
852     {
853       var url = UserFolderURL + "Contacts/new?contactEmail=" + email;
854       if (c_name)
855         url += "&contactFN=" + c_name;
856       openContactWindow(url);
857     }
858
859   return false; /* stop following the link */
860 }
861
862 function newEmailTo(sender) {
863   return openMailTo(document.menuTarget.innerHTML);
864 }
865
866 function expandUpperTree(node) {
867   var currentNode = node.parentNode;
868
869   while (currentNode.className != "dtree") {
870     if (currentNode.className == 'clip') {
871       var id = currentNode.getAttribute("id");
872       var number = parseInt(id.substr(2));
873       if (number > 0) {
874         var cn = mailboxTree.aNodes[number];
875         mailboxTree.nodeStatus(1, number, cn._ls);
876       }
877     }
878     currentNode = currentNode.parentNode;
879   }
880 }
881
882 function onHeaderClick(event) {
883   var headerId = this.getAttribute("id");
884   var newSortAttribute;
885   if (headerId == "subjectHeader")
886     newSortAttribute = "subject";
887   else if (headerId == "fromHeader")
888     newSortAttribute = "from";
889   else if (headerId == "dateHeader")
890     newSortAttribute = "date";
891   else
892     newSortAttribute = "arrival";
893
894   if (sorting["attribute"] == newSortAttribute)
895     sorting["ascending"] = !sorting["ascending"];
896   else {
897     sorting["attribute"] = newSortAttribute;
898     sorting["ascending"] = true;
899   }
900   refreshCurrentFolder();
901   
902   Event.stop(event);
903 }
904
905 function refreshCurrentFolder() {
906   openMailbox(currentMailbox, true);
907 }
908
909 function refreshFolderByType(type) {
910   if (currentMailboxType == type)
911     refreshCurrentFolder();
912 }
913
914 var mailboxSpanAcceptType = function(type) {
915   return (type == "mailRow");
916 }
917
918 var mailboxSpanEnter = function() {
919   this.addClassName("_dragOver");
920 }
921
922 var mailboxSpanExit = function() {
923   this.removeClassName("_dragOver");
924 }
925
926 var mailboxSpanDrop = function(data) {
927   var success = false;
928
929   if (data) {
930     var folder = this.parentNode.parentNode.getAttribute("dataname");
931     if (folder != currentMailbox)
932       success = (moveMessages(data, folder) == 0);
933   }
934   else
935     success = false;
936   
937   return success;
938 }
939     
940 var plusSignEnter = function() {
941   var nodeNr = parseInt(this.id.substr(2));
942   if (!mailboxTree.aNodes[nodeNr]._io)
943     this.plusSignTimer = setTimeout("openPlusSign('" + nodeNr + "');", 1000);
944 }
945       
946 var plusSignExit = function() {
947   if (this.plusSignTimer) {
948     clearTimeout(this.plusSignTimer);
949     this.plusSignTimer = null;
950   }
951 }
952         
953 function openPlusSign(nodeNr) {
954   mailboxTree.nodeStatus(1, nodeNr, mailboxTree.aNodes[nodeNr]._ls);
955   mailboxTree.aNodes[nodeNr]._io = 1;
956   this.plusSignTimer = null;
957 }
958
959 var messageListGhost = function () {
960   var newDiv = document.createElement("div");
961   //   newDiv.style.width = "25px;";
962   //   newDiv.style.height = "25px;";
963   newDiv.style.backgroundColor = "#aae;";
964   newDiv.style.border = "2px solid #a3a;";
965   newDiv.style.padding = "5px;";
966   newDiv.ghostOffsetX = 10;
967   newDiv.ghostOffsetY = 5;
968
969   var newImg = document.createElement("img");
970   newImg.src = ResourcesURL + "/message-mail.png";
971
972   var list = $("messageList");
973   var count = list.getSelectedRows().length;
974   newDiv.appendChild(newImg);
975   newDiv.appendChild(document.createElement("br"));
976   newDiv.appendChild(document.createTextNode(count + " messages..."));
977
978   return newDiv;
979 }
980
981 var messageListData = function(type) {
982   var rows = this.parentNode.parentNode.getSelectedRowsId();
983   var msgIds = new Array();
984   for (var i = 0; i < rows.length; i++)
985     msgIds.push(rows[i].substr(4));
986
987   return msgIds;
988 }
989
990 /* a model for a futur refactoring of the sortable table headers mechanism */
991 function configureMessageListEvents(table) {
992   if (table) {
993     table.multiselect = true;
994     // Each body row can load a message
995     Event.observe(table, "mousedown",
996                   onMessageSelectionChange.bindAsEventListener(table));    
997     // Sortable columns
998     configureSortableTableHeaders(table);
999   }
1000 }
1001
1002 function configureMessageListBodyEvents(table) {
1003   if (table) {
1004     // Page navigation
1005     var cell = table.tHead.rows[1].cells[0];
1006     if ($(cell).hasClassName("tbtv_navcell")) {
1007       var anchors = $(cell).childNodesWithTag("a");
1008       for (var i = 0; i < anchors.length; i++)
1009         Event.observe(anchors[i], "click", openMailboxAtIndex.bindAsEventListener(anchors[i]));
1010     }
1011
1012     rows = table.tBodies[0].rows;
1013     for (var i = 0; i < rows.length; i++) {
1014       Event.observe(rows[i], "mousedown", onRowClick);
1015       Event.observe(rows[i], "selectstart", listRowMouseDownHandler);
1016       Event.observe(rows[i], "contextmenu", onMessageContextMenu.bindAsEventListener(rows[i]));
1017       
1018       rows[i].dndTypes = function() { return new Array("mailRow"); };
1019       rows[i].dndGhost = messageListGhost;
1020       rows[i].dndDataForType = messageListData;
1021 //       document.DNDManager.registerSource(rows[i]);
1022
1023       for (var j = 0; j < rows[i].cells.length; j++) {
1024         var cell = rows[i].cells[j];
1025         Event.observe(cell, "mousedown", listRowMouseDownHandler);
1026         if (j == 2 || j == 3 || j == 5)
1027           Event.observe(cell, "dblclick", onMessageDoubleClick.bindAsEventListener(cell));
1028         else if (j == 4) {
1029           var img = cell.childNodesWithTag("img")[0];
1030           Event.observe(img, "click", mailListMarkMessage);
1031         }
1032       }
1033     }
1034   }
1035 }
1036
1037 function configureDragHandles() {
1038   var handle = $("verticalDragHandle");
1039   if (handle) {
1040     handle.addInterface(SOGoDragHandlesInterface);
1041     handle.leftMargin = 1;
1042     handle.leftBlock=$("leftPanel");
1043     handle.rightBlock=$("rightPanel");
1044   }
1045
1046   handle = $("rightDragHandle");
1047   if (handle) {
1048     handle.addInterface(SOGoDragHandlesInterface);
1049     handle.upperBlock=$("mailboxContent");
1050     handle.lowerBlock=$("messageContent");
1051   }
1052 }
1053
1054 /* dnd */
1055 function initDnd() {
1056   //   log("MailerUI initDnd");
1057
1058   var tree = $("mailboxTree");
1059   if (tree) {
1060     var images = tree.getElementsByTagName("img");
1061     for (var i = 0; i < images.length; i++) {
1062       if (images[i].id[0] == 'j') {
1063         images[i].dndAcceptType = mailboxSpanAcceptType;
1064         images[i].dndEnter = plusSignEnter;
1065         images[i].dndExit = plusSignExit;
1066         document.DNDManager.registerDestination(images[i]);
1067       }
1068     }
1069     var nodes = document.getElementsByClassName("nodeName", tree);
1070     for (var i = 0; i < nodes.length; i++) {
1071       nodes[i].dndAcceptType = mailboxSpanAcceptType;
1072       nodes[i].dndEnter = mailboxSpanEnter;
1073       nodes[i].dndExit = mailboxSpanExit;
1074       nodes[i].dndDrop = mailboxSpanDrop;
1075       document.DNDManager.registerDestination(nodes[i]);
1076     }
1077   }
1078 }
1079
1080 /* stub */
1081
1082 function refreshContacts() {
1083 }
1084
1085 function openInbox(node) {
1086   var done = false;
1087   openMailbox(node.parentNode.getAttribute("dataname"));
1088   var tree = $("mailboxTree");
1089   tree.selectedEntry = node;
1090   node.select();
1091   mailboxTree.o(1);
1092 }
1093
1094 function initMailer(event) {
1095   if (!document.body.hasClassName("popup")) {
1096 //     initDnd();
1097     initMailboxTree();
1098   }
1099 }
1100
1101 function initMailboxTree() {
1102   mailboxTree = new dTree("mailboxTree");
1103   mailboxTree.config.folderLinks = true;
1104   mailboxTree.config.hideRoot = true;
1105
1106   mailboxTree.icon.root = ResourcesURL + "/tbtv_account_17x17.gif";
1107   mailboxTree.icon.folder = ResourcesURL + "/tbtv_leaf_corner_17x17.gif";
1108   mailboxTree.icon.folderOpen   = ResourcesURL + "/tbtv_leaf_corner_17x17.gif";
1109   mailboxTree.icon.node = ResourcesURL + "/tbtv_leaf_corner_17x17.gif";
1110   mailboxTree.icon.line = ResourcesURL + "/tbtv_line_17x17.gif";
1111   mailboxTree.icon.join = ResourcesURL + "/tbtv_junction_17x17.gif";
1112   mailboxTree.icon.joinBottom   = ResourcesURL + "/tbtv_corner_17x17.gif";
1113   mailboxTree.icon.plus = ResourcesURL + "/tbtv_plus_17x17.gif";
1114   mailboxTree.icon.plusBottom   = ResourcesURL + "/tbtv_corner_plus_17x17.gif";
1115   mailboxTree.icon.minus = ResourcesURL + "/tbtv_minus_17x17.gif";
1116   mailboxTree.icon.minusBottom = ResourcesURL + "/tbtv_corner_minus_17x17.gif";
1117   mailboxTree.icon.nlPlus = ResourcesURL + "/tbtv_corner_plus_17x17.gif";
1118   mailboxTree.icon.nlMinus = ResourcesURL + "/tbtv_corner_minus_17x17.gif";
1119   mailboxTree.icon.empty = ResourcesURL + "/empty.gif";
1120
1121   mailboxTree.add(0, -1, '');
1122
1123   mailboxTree.pendingRequests = mailAccounts.length;
1124   activeAjaxRequests += mailAccounts.length;
1125   for (var i = 0; i < mailAccounts.length; i++) {
1126     var url = ApplicationBaseURL + "/" + mailAccounts[i] + "/mailboxes";
1127     triggerAjaxRequest(url, onLoadMailboxesCallback, mailAccounts[i]);
1128   }
1129 }
1130
1131 function updateMailboxTreeInPage() {
1132   $("folderTreeContent").update(mailboxTree);
1133
1134   var inboxFound = false;
1135   var tree = $("mailboxTree");
1136   var nodes = document.getElementsByClassName("node", tree);
1137   for (i = 0; i < nodes.length; i++) {
1138     Event.observe(nodes[i], "click",
1139                   onMailboxTreeItemClick.bindAsEventListener(nodes[i]));
1140     Event.observe(nodes[i], "contextmenu",
1141                   onFolderMenuClick.bindAsEventListener(nodes[i]));
1142     if (!inboxFound
1143         && nodes[i].parentNode.getAttribute("datatype") == "inbox") {
1144       openInbox(nodes[i]);
1145       inboxFound = true;
1146     }
1147   }
1148 }
1149
1150 function mailboxMenuNode(type, name) {
1151   var newNode = document.createElement("li");
1152   var icon = MailerUIdTreeExtension.folderIcons[type];
1153   if (!icon)
1154     icon = "tbtv_leaf_corner_17x17.gif";
1155   var image = document.createElement("img");
1156   image.src = ResourcesURL + "/" + icon;
1157   newNode.appendChild(image);
1158   var displayName = MailerUIdTreeExtension.folderNames[type];
1159   if (!displayName)
1160     displayName = name;
1161   newNode.appendChild(document.createTextNode(" " + displayName));
1162
1163   return newNode;
1164 }
1165
1166 function generateMenuForMailbox(mailbox, prefix, callback) {
1167   var menuDIV = document.createElement("div");
1168   $(menuDIV).addClassName("menu");
1169   menuDIV.setAttribute("id", prefix + "Submenu");
1170   var menu = document.createElement("ul");
1171   menuDIV.appendChild(menu);
1172   pageContent.appendChild(menuDIV);
1173
1174   var callbacks = new Array();
1175   if (mailbox.type != "account") {
1176     var newNode = document.createElement("li");
1177     newNode.mailbox = mailbox;
1178     newNode.appendChild(document.createTextNode(labels["This Folder"]));
1179     menu.appendChild(newNode);
1180     menu.appendChild(document.createElement("li"));
1181     callbacks.push(callback);
1182     callbacks.push("-");
1183   }
1184
1185   var submenuCount = 0;
1186   for (var i = 0; i < mailbox.children.length; i++) {
1187     var child = mailbox.children[i];
1188     var newNode = mailboxMenuNode(child.type, child.name);
1189     menu.appendChild(newNode);
1190     if (child.children.length > 0) {
1191       var newPrefix = prefix + submenuCount;
1192       var newSubmenuId = generateMenuForMailbox(child, newPrefix, callback);
1193       callbacks.push(newSubmenuId);
1194       submenuCount++;
1195     }
1196     else {
1197       newNode.mailbox = child;
1198       callbacks.push(callback);
1199     }
1200   }
1201   initMenu(menuDIV, callbacks);
1202
1203   return menuDIV.getAttribute("id");
1204 }
1205
1206 function updateMailboxMenus() {
1207   var mailboxActions = { move: onMailboxMenuMove,
1208                          copy: onMailboxMenuCopy };
1209
1210   for (key in mailboxActions) {
1211     var menuId = key + "MailboxMenu";
1212     var menuDIV = $(menuId);
1213     if (menuDIV)
1214       menuDIV.parentNode.removeChild(menuDIV);
1215
1216     menuDIV = document.createElement("div");
1217     pageContent = $("pageContent");
1218     pageContent.appendChild(menuDIV);
1219
1220     var menu = document.createElement("ul");
1221     menuDIV.appendChild(menu);
1222
1223     $(menuDIV).addClassName("menu");
1224     menuDIV.setAttribute("id", menuId);
1225
1226     var submenuIds = new Array();
1227     for (var i = 0; i < mailAccounts.length; i++) {
1228       var menuEntry = mailboxMenuNode("account", mailAccounts[i]);
1229       menu.appendChild(menuEntry);
1230       var mailbox = accounts[mailAccounts[i]];
1231       var newSubmenuId = generateMenuForMailbox(mailbox,
1232                                               key, mailboxActions[key]);
1233       submenuIds.push(newSubmenuId);
1234     }
1235     initMenu(menuDIV, submenuIds);
1236   }
1237 }
1238
1239 function onLoadMailboxesCallback(http) {
1240   if (http.readyState == 4
1241       && http.status == 200) {
1242     checkAjaxRequestsState();
1243     var newAccount = buildMailboxes(http.callbackData,
1244                                     http.responseText);
1245     accounts[http.callbackData] = newAccount;
1246     mailboxTree.addMailAccount(newAccount);
1247     mailboxTree.pendingRequests--;
1248     activeAjaxRequests--;
1249     if (!mailboxTree.pendingRequests) {
1250       updateMailboxTreeInPage();
1251       updateMailboxMenus();
1252       checkAjaxRequestsState();
1253     }
1254   }
1255
1256   //       var tree = $("mailboxTree");
1257   //       var treeNodes = document.getElementsByClassName("dTreeNode", tree);
1258   //       var i = 0;
1259   //       while (i < treeNodes.length
1260   //         && treeNodes[i].getAttribute("dataname") != currentMailbox)
1261   //     i++;
1262   //       if (i < treeNodes.length) {
1263   //     //     log("found mailbox");
1264   //     var links = document.getElementsByClassName("node", treeNodes[i]);
1265   //     if (tree.selectedEntry)
1266   //        tree.selectedEntry.deselect();
1267   //     links[0].select();
1268   //     tree.selectedEntry = links[0];
1269   //     expandUpperTree(links[0]);
1270   //       }
1271 }
1272
1273 function buildMailboxes(accountName, encoded) {
1274   var account = new Mailbox("account", accountName);
1275   var data = encoded.evalJSON(true);
1276   for (var i = 0; i < data.length; i++) {
1277     var currentNode = account;
1278     var names = data[i].path.split("/");
1279     for (var j = 1; j < (names.length - 1); j++) {
1280       var node = currentNode.findMailboxByName(names[j]);
1281       if (!node) {
1282         node = new Mailbox("additional", names[j]);
1283         currentNode.addMailbox(node);
1284       }
1285       currentNode = node;
1286     }
1287     var basename = names[names.length-1];
1288     var leaf = currentNode.findMailboxByName(basename);
1289     if (leaf)
1290       leaf.type = data[i].type;
1291     else {
1292       leaf = new Mailbox(data[i].type, basename);
1293       currentNode.addMailbox(leaf);
1294     }
1295   }
1296
1297   return account;
1298 }
1299
1300 function onMenuCreateFolder(event) {
1301   var name = window.prompt(labels["Name :"], "");
1302   if (name && name.length > 0) {
1303     var folderID = document.menuTarget.getAttribute("dataname");
1304     var urlstr = URLForFolderID(folderID) + "/createFolder?name=" + name;
1305     triggerAjaxRequest(urlstr, folderOperationCallback);
1306   }
1307 }
1308
1309 function onMenuRenameFolder(event) {
1310   var name = window.prompt(labels["Enter the new name of your folder :"]
1311                            ,
1312                            "");
1313   if (name && name.length > 0) {
1314     var folderID = document.menuTarget.getAttribute("dataname");
1315     var urlstr = URLForFolderID(folderID) + "/renameFolder?name=" + name;
1316     triggerAjaxRequest(urlstr, folderOperationCallback);
1317   }
1318 }
1319
1320 function onMenuDeleteFolder(event) {
1321   var answer = window.confirm(labels["Do you really want to move this folder into the trash ?"]);
1322   if (answer) {
1323     var folderID = document.menuTarget.getAttribute("dataname");
1324     var urlstr = URLForFolderID(folderID) + "/deleteFolder";
1325     triggerAjaxRequest(urlstr, folderOperationCallback);
1326   }
1327 }
1328
1329 function onMenuExpungeFolder(event) {
1330   var folderID = document.menuTarget.getAttribute("dataname");
1331   var urlstr = URLForFolderID(folderID) + "/expunge";
1332
1333   triggerAjaxRequest(urlstr, folderRefreshCallback, folderID);
1334 }
1335
1336 function onMenuEmptyTrash(event) {
1337   var folderID = document.menuTarget.getAttribute("dataname");
1338   var urlstr = URLForFolderID(folderID) + "/emptyTrash";
1339   triggerAjaxRequest(urlstr, folderOperationCallback, folderID);
1340
1341   if (folderID == currentMailbox) {
1342     var div = $('messageContent');
1343     for (var i = div.childNodes.length - 1; i > -1; i--)
1344       div.removeChild(div.childNodes[i]);
1345     refreshCurrentFolder();
1346   }
1347   var msgID = currentMessages[folderID];
1348   if (msgID)
1349     deleteCachedMessage(folderID + "/" + msgID);
1350 }
1351
1352 function _onMenuChangeToXXXFolder(event, folder) {
1353   var type = document.menuTarget.getAttribute("datatype");
1354   if (type == "additional")
1355     window.alert(labels["You need to choose a non-virtual folder!"]);
1356   else {
1357     var folderID = document.menuTarget.getAttribute("dataname");
1358     var number = folderID.split("/").length;
1359     if (number > 3)
1360       window.alert(labels["You need to choose a root subfolder!"]);
1361     else {
1362       var urlstr = URLForFolderID(folderID) + "/setAs" + folder + "Folder";
1363       triggerAjaxRequest(urlstr, folderOperationCallback);
1364     }
1365   }
1366 }
1367
1368 function onMenuChangeToDraftsFolder(event) {
1369   return _onMenuChangeToXXXFolder(event, "Drafts");
1370 }
1371
1372 function onMenuChangeToSentFolder(event) {
1373   return _onMenuChangeToXXXFolder(event, "Sent");
1374 }
1375
1376 function onMenuChangeToTrashFolder(event) {
1377   return _onMenuChangeToXXXFolder(event, "Trash");
1378 }
1379
1380 function onMenuLabelNone() {
1381   var rowId = document.menuTarget.getAttribute("id").substr(4);
1382   var messageId = currentMailbox + "/" + rowId;
1383   var urlstr = ApplicationBaseURL + messageId + "/removeAllLabels";
1384   triggerAjaxRequest(urlstr, messageFlagCallback,
1385                      { mailbox: currentMailbox, msg: rowId, label: null } );
1386 }
1387
1388 function _onMenuLabelFlagX(flag) {
1389   var flags = document.menuTarget.getAttribute("labels").split(" ");
1390
1391   var rowId = document.menuTarget.getAttribute("id").substr(4);
1392   var messageId = currentMailbox + "/" + rowId;
1393
1394   var operation = "add";
1395   if (flags.indexOf("label" + flag) > -1)
1396     operation = "remove";
1397   var urlstr = (ApplicationBaseURL + messageId
1398                 + "/" + operation + "Label" + flag);
1399   triggerAjaxRequest(urlstr, messageFlagCallback,
1400                      { mailbox: currentMailbox, msg: rowId,
1401                        label: operation + flag } );
1402 }
1403
1404 function onMenuLabelFlag1() {
1405   _onMenuLabelFlagX(1);
1406 }
1407
1408 function onMenuLabelFlag2() {
1409   _onMenuLabelFlagX(2);
1410 }
1411
1412 function onMenuLabelFlag3() {
1413   _onMenuLabelFlagX(3);
1414 }
1415
1416 function onMenuLabelFlag4() {
1417   _onMenuLabelFlagX(4);
1418 }
1419
1420 function onMenuLabelFlag5() {
1421   _onMenuLabelFlagX(5);
1422 }
1423
1424 function folderOperationCallback(http) {
1425   if (http.readyState == 4
1426       && isHttpStatus204(http.status))
1427     initMailboxTree();
1428   else
1429     window.alert(labels["Operation failed"]);
1430 }
1431
1432 function folderRefreshCallback(http) {
1433   if (http.readyState == 4
1434       && isHttpStatus204(http.status)) {
1435     var oldMailbox = http.callbackData;
1436     if (oldMailbox == currentMailbox)
1437       refreshCurrentFolder();
1438   }
1439   else
1440     window.alert(labels["Operation failed"]);
1441 }
1442
1443 function messageFlagCallback(http) {
1444   if (http.readyState == 4
1445       && isHttpStatus204(http.status)) {
1446     var data = http.callbackData;
1447     if (data["mailbox"] == currentMailbox) {
1448       var row = $("row_" + data["msg"]);
1449       var operation = data["label"];
1450       if (operation) {
1451         var labels = row.getAttribute("labels");
1452         var flags;
1453         if (labels.length > 0)
1454           flags = labels.split(" ");
1455         else
1456           flags = new Array();
1457         if (operation.substr(0, 3) == "add")
1458           flags.push("label" + operation.substr(3));
1459         else {
1460           var flag = "label" + operation.substr(6);
1461           var idx = flags.indexOf(flag);
1462           flags.splice(idx, 1);
1463         }
1464         row.setAttribute("labels", flags.join(" "));
1465       }
1466       else
1467         row.setAttribute("labels", "");
1468     }
1469   }
1470 }
1471
1472 function onLabelMenuPrepareVisibility() {
1473   var messageList = $("messageList");
1474   var rows = messageList.getSelectedRows();
1475
1476   var flags = {};
1477   for (var i = 1; i < 6; i++)
1478     flags["label" + i] = true;
1479   for (var i = 0; i < rows.length; i++) {
1480     var rowFlags = rows[i].getAttribute("labels").split(" ");
1481     for (var flag in flags)
1482       if (flags[flag] && rowFlags.indexOf(flag) == -1)
1483         flags[flag] = false;
1484   }
1485
1486   var lis = this.childNodesWithTag("ul")[0].childNodesWithTag("li")
1487   var isFlagged = false;
1488   for (var i = 1; i < 6; i++) {
1489     if (flags["label" + i]) {
1490       isFlagged = true;
1491       lis[1 + i].addClassName("_chosen");
1492     }
1493     else
1494       lis[1 + i].removeClassName("_chosen");
1495   }
1496   if (isFlagged)
1497     lis[0].removeClassName("_chosen");
1498   else
1499     lis[0].addClassName("_chosen");
1500 }
1501
1502 function getMenus() {
1503   var menus = {}
1504   menus["accountIconMenu"] = new Array(null, null, onMenuCreateFolder, null,
1505                                        null, null);
1506   menus["inboxIconMenu"] = new Array(null, null, null, "-", null,
1507                                      onMenuCreateFolder, onMenuExpungeFolder,
1508                                      "-", null,
1509                                      onMenuSharing);
1510   menus["trashIconMenu"] = new Array(null, null, null, "-", null,
1511                                      onMenuCreateFolder, onMenuExpungeFolder,
1512                                      onMenuEmptyTrash, "-", null,
1513                                      onMenuSharing);
1514   menus["mailboxIconMenu"] = new Array(null, null, null, "-", null,
1515                                        onMenuCreateFolder,
1516                                        onMenuRenameFolder,
1517                                        onMenuExpungeFolder,
1518                                        onMenuDeleteFolder,
1519                                        "folderTypeMenu",
1520                                        "-", null,
1521                                        onMenuSharing);
1522   menus["addressMenu"] = new Array(newContactFromEmail, newEmailTo, null);
1523   menus["messageListMenu"] = new Array(onMenuOpenMessage, "-",
1524                                        onMenuReplyToSender,
1525                                        onMenuReplyToAll,
1526                                        onMenuForwardMessage, null,
1527                                        "-", "moveMailboxMenu",
1528                                        "copyMailboxMenu", "label-menu",
1529                                        "mark-menu", "-", null,
1530                                        onMenuViewMessageSource, null,
1531                                        null, onMenuDeleteMessage);
1532   menus["messageContentMenu"] = new Array(onMenuReplyToSender,
1533                                           onMenuReplyToAll,
1534                                           onMenuForwardMessage,
1535                                           null, "moveMailboxMenu",
1536                                           "copyMailboxMenu",
1537                                           "-", "label-menu", "mark-menu",
1538                                           "-",
1539                                           null, onMenuViewMessageSource,
1540                                           null, onPrintCurrentMessage,
1541                                           onMenuDeleteMessage);
1542   menus["folderTypeMenu"] = new Array(onMenuChangeToSentFolder,
1543                                       onMenuChangeToDraftsFolder,
1544                                       onMenuChangeToTrashFolder);
1545
1546   menus["label-menu"] = new Array(onMenuLabelNone, "-", onMenuLabelFlag1,
1547                                   onMenuLabelFlag2, onMenuLabelFlag3,
1548                                   onMenuLabelFlag4, onMenuLabelFlag5);
1549   menus["mark-menu"] = new Array(null, null, null, null, "-", null, "-",
1550                                  null, null, null);
1551   menus["searchMenu"] = new Array(setSearchCriteria, setSearchCriteria,
1552                                   setSearchCriteria, setSearchCriteria,
1553                                   setSearchCriteria);
1554   var labelMenu = $("label-menu");
1555   if (labelMenu)
1556     labelMenu.prepareVisibility = onLabelMenuPrepareVisibility;
1557
1558   return menus;
1559 }
1560
1561 addEvent(window, 'load', initMailer);
1562
1563 function Mailbox(type, name) {
1564   this.type = type;
1565   this.name = name;
1566   this.parentFolder = null;
1567   this.children = new Array();
1568   return this;
1569 }
1570
1571 Mailbox.prototype.dump = function(indent) {
1572   if (!indent)
1573     indent = 0;
1574   log(" ".repeat(indent) + this.name);
1575   for (var i = 0; i < this.children.length; i++) {
1576     this.children[i].dump(indent + 2);
1577   }
1578 }
1579
1580 Mailbox.prototype.fullName = function() {
1581   var fullName = "";
1582
1583   var currentFolder = this;
1584   while (currentFolder.parentFolder) {
1585     fullName = "/folder" + currentFolder.name + fullName;
1586     currentFolder = currentFolder.parentFolder;
1587   }
1588
1589   return "/" + currentFolder.name + fullName;
1590 }
1591
1592 Mailbox.prototype.findMailboxByName = function(name) {
1593   var mailbox = null;
1594
1595   var i = 0;
1596   while (!mailbox && i < this.children.length)
1597     if (this.children[i].name == name)
1598       mailbox = this.children[i];
1599     else
1600       i++;
1601
1602   return mailbox;
1603 }
1604
1605 Mailbox.prototype.addMailbox = function(mailbox) {
1606   mailbox.parentFolder = this;
1607   this.children.push(mailbox);
1608 }