]> err.no Git - scalable-opengroupware.org/blobdiff - UI/WebServerResources/MailerUI.js
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1305 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / UI / WebServerResources / MailerUI.js
index cc844680598a626f11ca09890333e740b2f9743e..f2568018bc7b9f031b1227ae8d589d8fc7e85b90 100644 (file)
@@ -9,11 +9,14 @@ if (typeof textMailAccounts != 'undefined') {
     mailAccounts = new Array();
 }
 
-var currentMessages = new Array();
-var maxCachedMessages = 20;
-var cachedMessages = new Array();
-var currentMailbox = null;
-var currentMailboxType = "";
+var Mailer = {
+ currentMailbox: null,
+ currentMailboxType: "",
+ currentMessages: {},
+ maxCachedMessages: 20,
+ cachedMessages: new Array(),
+ foldersStateTimer: false
+};
 
 var usersRightsWindowHeight = 320;
 var usersRightsWindowWidth = 400;
@@ -41,7 +44,7 @@ function openMessageWindow(msguid, url) {
 function onMessageDoubleClick(event) {
   var action;
 
-  if (currentMailboxType == "draft")
+  if (Mailer.currentMailboxType == "draft")
     action = "edit";
   else
     action = "popupview";
@@ -57,8 +60,8 @@ function toggleMailSelect(sender) {
 
 function openAddressbook(sender) {
   var urlstr;
-   
-  urlstr = ApplicationBaseURL + "/../Contacts/?popup=YES";
+
+  urlstr = ApplicationBaseURL + "../Contacts/?popup=YES";
   var w = window.open(urlstr, "Addressbook",
                      "width=640,height=400,resizable=1,scrollbars=1,toolbar=0,"
                      + "location=no,directories=0,status=0,menubar=0,copyhistory=0");
@@ -129,7 +132,10 @@ function markMailReadInWindow(win, msguid) {
 
 function openMessageWindowsForSelection(action, firstOnly) {
   if (document.body.hasClassName("popup")) {
-    return true;
+    var url = window.location.href;
+    var parts = url.split("/");
+    parts[parts.length-1] = action;
+    window.location.href = parts.join("/");
   }
   else {
     var messageList = $("messageList");
@@ -137,7 +143,7 @@ function openMessageWindowsForSelection(action, firstOnly) {
     if (rows.length > 0) {
       for (var i = 0; i < rows.length; i++) {
        openMessageWindow(rows[i].substr(4),
-                         ApplicationBaseURL + currentMailbox
+                         ApplicationBaseURL + Mailer.currentMailbox
                          + "/" + rows[i].substr(4)
                          + "/" + action);
        if (firstOnly)
@@ -163,7 +169,7 @@ function mailListMarkMessage(event) {
     action = 'markMessageUnread';
     markread = false;
   }
-  var url = ApplicationBaseURL + currentMailbox + "/" + msguid + "/" + action;
+  var url = ApplicationBaseURL + Mailer.currentMailbox + "/" + msguid + "/" + action;
 
   var data = { "window": window, "msguid": msguid, "markread": markread };
   triggerAjaxRequest(url, mailListMarkMessageCallback, data);
@@ -208,20 +214,24 @@ function ml_lowlight(sender) {
 /* bulk delete of messages */
 
 function deleteSelectedMessages(sender) {
-  var messageList = $("messageList");
-  var rowIds = messageList.getSelectedRowsId();
-
-  for (var i = 0; i < rowIds.length; i++) {
-    var url;
-    var rowId = rowIds[i].substr(4);
-    var messageId = currentMailbox + "/" + rowId;
-    url = ApplicationBaseURL + messageId + "/trash";
-    deleteMessageRequestCount++;
-    var data = { "id": rowId, "mailbox": currentMailbox, "messageId": messageId };
-    triggerAjaxRequest(url, deleteSelectedMessagesCallback, data);
-  }
-
-  return false;
+   var messageList = $("messageList");
+   var rowIds = messageList.getSelectedRowsId();
+  
+   if (rowIds.length > 0) {
+      for (var i = 0; i < rowIds.length; i++) {
+       var url;
+       var rowId = rowIds[i].substr(4);
+       var messageId = Mailer.currentMailbox + "/" + rowId;
+       url = ApplicationBaseURL + messageId + "/trash";
+       deleteMessageRequestCount++;
+       var data = { "id": rowId, "mailbox": Mailer.currentMailbox, "messageId": messageId };
+       triggerAjaxRequest(url, deleteSelectedMessagesCallback, data);
+      }
+   }
+   else
+     window.alert(labels["Please select a message."]);
+   
+   return false;
 }
 
 function deleteSelectedMessagesCallback(http) {
@@ -229,19 +239,28 @@ function deleteSelectedMessagesCallback(http) {
     if (isHttpStatus204(http.status)) {
       var data = http.callbackData;
       deleteCachedMessage(data["messageId"]);
-      if (currentMailbox == data["mailbox"]) {
-       
+      deleteMessageRequestCount--;
+      if (Mailer.currentMailbox == data["mailbox"]) {
        var div = $('messageContent');
-       if (currentMessages[currentMailbox] == data["id"]) {
+       if (Mailer.currentMessages[Mailer.currentMailbox] == data["id"]) {
          div.update();
-         currentMessages[currentMailbox] = null;       
+         Mailer.currentMessages[Mailer.currentMailbox] = null; 
        }
 
        var row = $("row_" + data["id"]);
+       var nextRow = row.next("tr");
+       if (!nextRow)
+         nextRow = row.previous("tr");
        row.parentNode.removeChild(row);
 //     row.addClassName("deleted"); // when we'll offer "mark as deleted"
-
-       deleteMessageRequestCount--;
+      
+       if (deleteMessageRequestCount == 0) {
+         if (nextRow) {
+           Mailer.currentMessages[Mailer.currentMailbox] = nextRow.getAttribute("id").substr(4);
+           nextRow.select();
+           loadMessage(Mailer.currentMessages[Mailer.currentMailbox]);
+         }
+       }
       }
     }
   }
@@ -254,8 +273,7 @@ function deleteDraft(url) {
   new Ajax.Request(url, {
     method: 'post',
     onFailure: function(transport) {
-       if (!isHttpStatus204)
-         log("draftDeleteCallback: problem during ajax request: " + transport.status);
+       log("draftDeleteCallback: problem during ajax request: " + transport.status);
       }
     });
 }
@@ -268,7 +286,7 @@ function moveMessages(rowIds, folder) {
 
     /* send AJAX request (synchronously) */
          
-    var messageId = currentMailbox + "/" + rowIds[i];
+    var messageId = Mailer.currentMailbox + "/" + rowIds[i];
     url = (ApplicationBaseURL + messageId
           + "/move?tofolder=" + folder);
     http = createHTTPClient();
@@ -278,10 +296,10 @@ function moveMessages(rowIds, folder) {
       var row = $("row_" + rowIds[i]);
       row.parentNode.removeChild(row);
       deleteCachedMessage(messageId);
-      if (currentMessages[currentMailbox] == rowIds[i]) {
+      if (Mailer.currentMessages[Mailer.currentMailbox] == rowIds[i]) {
        var div = $('messageContent');
        div.update();
-       currentMessages[currentMailbox] = null;
+       Mailer.currentMessages[Mailer.currentMailbox] = null;
       }
     }
     else /* request failed */
@@ -299,8 +317,24 @@ function moveMessages(rowIds, folder) {
 }
 
 function onMenuDeleteMessage(event) {
-  deleteSelectedMessages();
-  preventDefault(event);
+    deleteSelectedMessages();
+    preventDefault(event);
+}
+
+function deleteMessage(url, id, mailbox, messageId) {
+  var data = { "id": id, "mailbox": mailbox, "messageId": messageId };
+  deleteMessageRequestCount++;
+  triggerAjaxRequest(url, deleteSelectedMessagesCallback, data);
+}
+
+function deleteMessageWithDelay(url, id, mailbox, messageId) {
+  /* this is called by UIxMailPopupView with window.opener */
+  setTimeout("deleteMessage('" +
+            url + "', '" +
+            id + "', '" +
+            mailbox + "', '" +
+            messageId + "')",
+            50);
 }
 
 function onPrintCurrentMessage(event) {
@@ -331,9 +365,9 @@ function onMailboxTreeItemClick(event) {
   $("searchValue").value = "";
   initCriteria();
 
-  currentMailboxType = this.parentNode.getAttribute("datatype");
-  if (currentMailboxType == "account" || currentMailboxType == "additional") {
-    currentMailbox = mailbox;
+  Mailer.currentMailboxType = this.parentNode.getAttribute("datatype");
+  if (Mailer.currentMailboxType == "account" || Mailer.currentMailboxType == "additional") {
+    Mailer.currentMailbox = mailbox;
     $("messageContent").update();
     var table = $("messageList");
     var head = table.tHead;
@@ -351,19 +385,30 @@ function onMailboxTreeItemClick(event) {
 
 function _onMailboxMenuAction(menuEntry, error, actionName) {
   var targetMailbox = menuEntry.mailbox.fullName();
+  var messages = new Array();
 
-  if (targetMailbox == currentMailbox)
+  if (targetMailbox == Mailer.currentMailbox)
     window.alert(labels[error]);
   else {
-    var message;
     if (document.menuTarget.tagName == "DIV")
-      message = currentMessages[currentMailbox];
+      // Menu called from message content view
+      messages.push(Mailer.currentMessages[Mailer.currentMailbox]);
+    else if (Object.isArray(document.menuTarget))
+      // Menu called from multiple selection in messages list view
+      messages = $(document.menuTarget).collect(function(row) {
+         return row.getAttribute("id").substr(4);
+       });
     else
-      message = document.menuTarget.getAttribute("id").substr(4);
-
-    var urlstr = (URLForFolderID(currentMailbox) + "/" + message
-                 + "/" + actionName + "?folder=" + targetMailbox);
-    triggerAjaxRequest(urlstr, folderRefreshCallback, currentMailbox);
+      // Menu called from one selection in messages list view
+      messages.push(document.menuTarget.getAttribute("id").substr(4));
+
+    var url_prefix = URLForFolderID(Mailer.currentMailbox) + "/";
+    messages.each(function(msgid, i) {
+       var url = url_prefix + msgid + "/" + actionName
+         + "?folder=" + targetMailbox;
+       triggerAjaxRequest(url, folderRefreshCallback,
+                          ((i == messages.size() - 1)?Mailer.currentMailbox:""));
+      });
   }
 }
 
@@ -396,25 +441,30 @@ function onComposeMessage() {
 }
 
 function composeNewMessage() {
-  var account = currentMailbox.split("/")[1];
+  var account = Mailer.currentMailbox.split("/")[1];
   var url = ApplicationBaseURL + "/" + account + "/compose";
   openMailComposeWindow(url);
 }
 
 function openMailbox(mailbox, reload, idx) {
-  if (mailbox != currentMailbox || reload) {
-    currentMailbox = mailbox;
+  if (mailbox != Mailer.currentMailbox || reload) {
+    Mailer.currentMailbox = mailbox;
     var url = ApplicationBaseURL + encodeURI(mailbox) + "/view?noframe=1";
-    var messageContent = $("messageContent");
-    messageContent.update();
-    lastClickedRow = -1; // from generic.js
-
+    
+    if (!reload || idx) {
+      var messageContent = $("messageContent");
+      messageContent.update();
+      lastClickedRow = -1; // from generic.js
+    }
+    
     var currentMessage;
+      
     if (!idx) {
-      currentMessage = currentMessages[mailbox];
+      currentMessage = Mailer.currentMessages[mailbox];
       if (currentMessage) {
-       loadMessage(currentMessage);
        url += '&pageforuid=' + currentMessage;
+       if (!reload)
+         loadMessage(currentMessage);
       }
     }
 
@@ -454,7 +504,7 @@ function openMailbox(mailbox, reload, idx) {
 }
 
 function openMailboxAtIndex(event) {
-  openMailbox(currentMailbox, true, this.getAttribute("idx"));
+  openMailbox(Mailer.currentMailbox, true, this.getAttribute("idx"));
 
   Event.stop(event);
 }
@@ -465,7 +515,7 @@ function messageListCallback(http) {
   
   if (http.readyState == 4
       && http.status == 200) {
-    document.messageListAjaxRequest = null;    
+    document.messageListAjaxRequest = null;
 
     if (table) {
       // Update table
@@ -494,7 +544,10 @@ function messageListCallback(http) {
       if (row) {
        row.select();
        lastClickedRow = row.rowIndex - $(row).up('table').down('thead').getElementsByTagName('tr').length;  
-       div.scrollTop = row.rowIndex * row.getHeight(); // scroll to selected message
+       var rowPosition = row.rowIndex * row.getHeight();
+       if ($(row).up('div').getHeight() > rowPosition)
+         rowPosition = 0;
+       div.scrollTop = rowPosition; // scroll to selected message
       }
       else
        $("messageContent").update();
@@ -541,7 +594,7 @@ function quotasCallback(http) {
     }
     
     if (hasQuotas) {
-      var treePath = currentMailbox.split("/");
+      var treePath = Mailer.currentMailbox.split("/");
       var quotasMB = new Array();
       for (var i = 2; i < treePath.length; i++)
        quotasMB.push(treePath[i].substr(6));
@@ -558,16 +611,15 @@ function quotasCallback(http) {
 
 function onMessageContextMenu(event) {
   var menu = $('messageListMenu');
-  Event.observe(menu, "hideMenu", onMessageContextMenuHide);
-  popupMenu(event, "messageListMenu", this);
-
   var topNode = $('messageList');
   var selectedNodes = topNode.getSelectedRows();
-  for (var i = 0; i < selectedNodes.length; i++)
-    selectedNodes[i].deselect();
-  topNode.menuSelectedRows = selectedNodes;
-  topNode.menuSelectedEntry = this;
-  this.select();
+
+  Event.observe(menu, "hideMenu", onMessageContextMenuHide);
+  
+  if (selectedNodes.length > 1)
+    popupMenu(event, "messagesListMenu", selectedNodes);
+  else
+    popupMenu(event, "messageListMenu", this);    
 }
 
 function onMessageContextMenuHide(event) {
@@ -633,11 +685,11 @@ function deleteCachedMessage(messageId) {
   var done = false;
   var counter = 0;
 
-  while (counter < cachedMessages.length
+  while (counter < Mailer.cachedMessages.length
         && !done)
-    if (cachedMessages[counter]
-       && cachedMessages[counter]['idx'] == messageId) {
-      cachedMessages.splice(counter, 1);
+    if (Mailer.cachedMessages[counter]
+       && Mailer.cachedMessages[counter]['idx'] == messageId) {
+      Mailer.cachedMessages.splice(counter, 1);
       done = true;
     }
     else
@@ -648,11 +700,11 @@ function getCachedMessage(idx) {
   var message = null;
   var counter = 0;
 
-  while (counter < cachedMessages.length
+  while (counter < Mailer.cachedMessages.length
         && message == null)
-    if (cachedMessages[counter]
-       && cachedMessages[counter]['idx'] == currentMailbox + '/' + idx)
-      message = cachedMessages[counter];
+    if (Mailer.cachedMessages[counter]
+       && Mailer.cachedMessages[counter]['idx'] == Mailer.currentMailbox + '/' + idx)
+      message = Mailer.cachedMessages[counter];
     else
       counter++;
 
@@ -664,14 +716,14 @@ function storeCachedMessage(cachedMessage) {
   var timeOldest = -1;
   var counter = 0;
 
-  if (cachedMessages.length < maxCachedMessages)
-    oldest = cachedMessages.length;
+  if (Mailer.cachedMessages.length < Mailer.maxCachedMessages)
+    oldest = Mailer.cachedMessages.length;
   else {
-    while (cachedMessages[counter]) {
+    while (Mailer.cachedMessages[counter]) {
       if (oldest == -1
-         || cachedMessages[counter]['time'] < timeOldest) {
+         || Mailer.cachedMessages[counter]['time'] < timeOldest) {
        oldest = counter;
-       timeOldest = cachedMessages[counter]['time'];
+       timeOldest = Mailer.cachedMessages[counter]['time'];
       }
       counter++;
     }
@@ -680,7 +732,7 @@ function storeCachedMessage(cachedMessage) {
       oldest = 0;
   }
 
-  cachedMessages[oldest] = cachedMessage;
+  Mailer.cachedMessages[oldest] = cachedMessage;
 }
 
 function onMessageSelectionChange() {
@@ -688,9 +740,8 @@ function onMessageSelectionChange() {
 
   if (rows.length == 1) {
     var idx = rows[0].substr(4);
-
-    if (currentMessages[currentMailbox] != idx) {
-      currentMessages[currentMailbox] = idx;
+    if (Mailer.currentMessages[Mailer.currentMailbox] != idx) {
+      Mailer.currentMessages[Mailer.currentMailbox] = idx;
       loadMessage(idx);
     }
   }
@@ -706,7 +757,7 @@ function loadMessage(idx) {
 
   markMailInWindow(window, idx, true);
   if (cachedMessage == null) {
-    var url = (ApplicationBaseURL + currentMailbox + "/"
+    var url = (ApplicationBaseURL + Mailer.currentMailbox + "/"
               + idx + "/view?noframe=1");
     document.messageAjaxRequest
       = triggerAjaxRequest(url, messageCallback, idx);
@@ -725,34 +776,89 @@ function configureLinksInMessage() {
   var mailContentDiv = document.getElementsByClassName('mailer_mailcontent',
                                                       messageDiv)[0];
   if (!document.body.hasClassName("popup"))
-    Event.observe(mailContentDiv, "contextmenu",
-                 onMessageContentMenu.bindAsEventListener(mailContentDiv));
+    mailContentDiv.observe("contextmenu", onMessageContentMenu);
+
   var anchors = messageDiv.getElementsByTagName('a');
   for (var i = 0; i < anchors.length; i++)
     if (anchors[i].href.substring(0,7) == "mailto:") {
-      Event.observe(anchors[i], "click",
-                   onEmailAddressClick.bindAsEventListener(anchors[i]));
-      Event.observe(anchors[i], "contextmenu",
-                   onEmailAddressClick.bindAsEventListener(anchors[i]));
+      $(anchors[i]).observe("click", onEmailTo);
+      $(anchors[i]).observe("contextmenu", onEmailAddressClick);
     }
     else
-      Event.observe(anchors[i], "click",
-                   onMessageAnchorClick.bindAsEventListener(anchors[i]));
+      $(anchors[i]).observe("click", onMessageAnchorClick);
+
+  var images = messageDiv.getElementsByTagName('img');
+  for (var i = 0; i < images.length; i++)
+    $(images[i]).observe("contextmenu", onImageClick);
 
   var editDraftButton = $("editDraftButton");
   if (editDraftButton)
     Event.observe(editDraftButton, "click",
                  onMessageEditDraft.bindAsEventListener(editDraftButton));
+
+  configureiCalLinksInMessage();
+}
+
+function configureiCalLinksInMessage() {
+  var buttons = { "iCalendarAccept": "accept",
+                 "iCalendarDecline": "decline",
+                 "iCalendarTentative": "tentative",
+                 "iCalendarUpdateUserStatus": "updateUserStatus",
+                 "iCalendarAddToCalendar": "addToCalendar",
+                 "iCalendarDeleteFromCalendar": "deleteFromCalendar" };
+
+  for (var key in buttons) {
+    var button = $(key);
+    if (button) {
+      button.action = buttons[key];
+      Event.observe(button, "click",
+                   onICalendarButtonClick.bindAsEventListener(button));
+    }
+  }
+}
+
+function onICalendarButtonClick(event) {
+  var link = $("iCalendarAttachment").value;
+  if (link) {
+    var urlstr = link + "/" + this.action;
+    triggerAjaxRequest(urlstr, ICalendarButtonCallback,
+                      Mailer.currentMailbox + "/"
+                      + Mailer.currentMessages[Mailer.currentMailbox]);
+  }
+  else
+    log("no link");
+}
+
+function ICalendarButtonCallback(http) {
+  if (http.readyState == 4)
+    if (isHttpStatus204(http.status)) {
+      var oldMsg = http.callbackData;
+      var msg = Mailer.currentMailbox + "/" + Mailer.currentMessages[Mailer.currentMailbox];
+      if (oldMsg == msg) {
+       deleteCachedMessage(oldMsg);
+       loadMessage(Mailer.currentMessages[Mailer.currentMailbox]);
+      }
+    }
+    else {
+      window.alert("received code: " + http.status);
+    }
 }
 
 function resizeMailContent() {
   var headerTable = document.getElementsByClassName('mailer_fieldtable')[0];
   var contentDiv = document.getElementsByClassName('mailer_mailcontent')[0];
   
-  contentDiv.setStyle({ 'top': (Element.getHeight(headerTable) + headerTable.offsetTop) + 'px' });
+  contentDiv.setStyle({ 'top':
+       (Element.getHeight(headerTable) + headerTable.offsetTop) + 'px' });
 }
 
 function onMessageContentMenu(event) {
+  var element = getTarget(event);
+  if ((element.tagName == 'A' && element.href.substring(0,7) == "mailto:")
+      || element.tagName == 'IMG')
+    // Don't show the default contextual menu; let the click propagate to 
+    // other observers
+    return true;
   popupMenu(event, 'messageContentMenu', this);
 }
 
@@ -762,6 +868,8 @@ function onMessageEditDraft(event) {
 
 function onEmailAddressClick(event) {
   popupMenu(event, 'addressMenu', this);
+  preventDefault(event);
+  return false;
 }
 
 function onMessageAnchorClick(event) {
@@ -769,6 +877,12 @@ function onMessageAnchorClick(event) {
   preventDefault(event);
 }
 
+function onImageClick(event) {
+  popupMenu(event, 'imageMenu', this);
+  preventDefault(event);
+  return false;
+}
+
 function messageCallback(http) {
   var div = $('messageContent');
 
@@ -781,7 +895,7 @@ function messageCallback(http) {
     
     if (http.callbackData) {
       var cachedMessage = new Array();
-      cachedMessage['idx'] = currentMailbox + '/' + http.callbackData;
+      cachedMessage['idx'] = Mailer.currentMailbox + '/' + http.callbackData;
       cachedMessage['time'] = (new Date()).getTime();
       cachedMessage['text'] = http.responseText;
       if (cachedMessage['text'].length < 30000)
@@ -866,7 +980,7 @@ function onMenuViewMessageSource(event) {
   var rows = messageList.getSelectedRowsId();
 
   if (rows.length > 0) {
-    var url = (ApplicationBaseURL + currentMailbox + "/"
+    var url = (ApplicationBaseURL + Mailer.currentMailbox + "/"
               + rows[0].substr(4) + "/viewsource");
     openMailComposeWindow(url);
   }
@@ -874,6 +988,14 @@ function onMenuViewMessageSource(event) {
   preventDefault(event);
 }
 
+function saveImage(event) {
+  var img = document.menuTarget;
+  var url = img.getAttribute("src");
+  var urlAsAttachment = url.replace(/(\/[^\/]*)$/,"/asAttachment$1");
+
+  window.location.href = urlAsAttachment;
+}
+
 /* contacts */
 function newContactFromEmail(event) {
   var mailto = document.menuTarget.innerHTML;
@@ -891,6 +1013,12 @@ function newContactFromEmail(event) {
   return false; /* stop following the link */
 }
 
+function onEmailTo(event) {
+  openMailTo(this.innerHTML.strip());
+  preventDefault(event);
+  return false;
+}
+
 function newEmailTo(sender) {
   return openMailTo(document.menuTarget.innerHTML);
 }
@@ -912,6 +1040,9 @@ function expandUpperTree(node) {
 }
 
 function onHeaderClick(event) {
+  if (TableKit.Resizable._onHandle)
+    return;
+  
   var headerId = this.getAttribute("id");
   var newSortAttribute;
   if (headerId == "subjectHeader")
@@ -935,11 +1066,11 @@ function onHeaderClick(event) {
 }
 
 function refreshCurrentFolder() {
-  openMailbox(currentMailbox, true);
+  openMailbox(Mailer.currentMailbox, true);
 }
 
 function refreshFolderByType(type) {
-  if (currentMailboxType == type)
+  if (Mailer.currentMailboxType == type)
     refreshCurrentFolder();
 }
 
@@ -960,7 +1091,7 @@ var mailboxSpanDrop = function(data) {
 
   if (data) {
     var folder = this.parentNode.parentNode.getAttribute("dataname");
-    if (folder != currentMailbox)
+    if (folder != Mailer.currentMailbox)
       success = (moveMessages(data, folder) == 0);
   }
   else
@@ -1124,11 +1255,15 @@ function openInbox(node) {
 }
 
 function initMailer(event) {
-  if (!document.body.hasClassName("popup")) {
+  if (!$(document.body).hasClassName("popup")) {
 //     initDnd();
     initMailboxTree();
     initMessageCheckTimer();
   }
+  
+  // Default sort options
+  sorting["attribute"] = "date";
+  sorting["ascending"] = false;
 }
 
 function initMessageCheckTimer() {
@@ -1194,6 +1329,7 @@ function updateMailboxTreeInPage() {
                  onFolderMenuClick.bindAsEventListener(nodes[i]));
     if (!inboxFound
        && nodes[i].parentNode.getAttribute("datatype") == "inbox") {
+      Mailer.currentMailboxType = "inbox";
       openInbox(nodes[i]);
       inboxFound = true;
     }
@@ -1282,7 +1418,7 @@ function updateMailboxMenus() {
       menu.appendChild(menuEntry);
       var mailbox = accounts[mailAccounts[i]];
       var newSubmenuId = generateMenuForMailbox(mailbox,
-                                             key, mailboxActions[key]);
+                                               key, mailboxActions[key]);
       submenuIds.push(newSubmenuId);
     }
     initMenu(menuDIV, submenuIds);
@@ -1304,6 +1440,7 @@ function onLoadMailboxesCallback(http) {
        updateMailboxTreeInPage();
        updateMailboxMenus();
        checkAjaxRequestsState();
+       getFoldersState();
       }
     }
   }
@@ -1312,7 +1449,7 @@ function onLoadMailboxesCallback(http) {
   //       var treeNodes = document.getElementsByClassName("dTreeNode", tree);
   //       var i = 0;
   //       while (i < treeNodes.length
-  //        && treeNodes[i].getAttribute("dataname") != currentMailbox)
+  //        && treeNodes[i].getAttribute("dataname") != Mailer.currentMailbox)
   //    i++;
   //       if (i < treeNodes.length) {
   //    //     log("found mailbox");
@@ -1352,6 +1489,45 @@ function buildMailboxes(accountName, encoded) {
   return account;
 }
 
+function getFoldersState() {
+  if (mailAccounts.length > 0) {
+    var urlstr =  ApplicationBaseURL + "foldersState";
+    triggerAjaxRequest(urlstr, getFoldersStateCallback);
+  }
+}
+
+function getFoldersStateCallback(http) {
+  if (http.readyState == 4
+      && http.status == 200) {
+    if (http.responseText.length > 0) {
+      // The response text is a JSOn representation
+      // of the folders that were left opened.
+      var data = http.responseText.evalJSON(true);
+      for (var i = 1; i < mailboxTree.aNodes.length; i++) {
+       if ($(data).indexOf(mailboxTree.aNodes[i].dataname) > 0)
+         // If the folder is found, open it
+         mailboxTree.o(i);
+      }
+    }
+  }
+  mailboxTree.autoSync();
+}
+
+function saveFoldersState() {
+  if (mailAccounts.length > 0) {
+    var foldersState = mailboxTree.getFoldersState();
+    var urlstr =  ApplicationBaseURL + "saveFoldersState" + "?expandedFolders=" + foldersState;
+    triggerAjaxRequest(urlstr, saveFoldersStateCallback);
+  }
+}
+
+function saveFoldersStateCallback(http) {
+  if (http.readyState == 4
+      && isHttpStatus204(http.status)) {
+    log ("folders state saved");
+  }
+}
+
 function onMenuCreateFolder(event) {
   var name = window.prompt(labels["Name :"], "");
   if (name && name.length > 0) {
@@ -1392,13 +1568,13 @@ function onMenuEmptyTrash(event) {
   var urlstr = URLForFolderID(folderID) + "/emptyTrash";
   triggerAjaxRequest(urlstr, folderOperationCallback, folderID);
 
-  if (folderID == currentMailbox) {
+  if (folderID == Mailer.currentMailbox) {
     var div = $('messageContent');
     for (var i = div.childNodes.length - 1; i > -1; i--)
       div.removeChild(div.childNodes[i]);
     refreshCurrentFolder();
   }
-  var msgID = currentMessages[folderID];
+  var msgID = Mailer.currentMessages[folderID];
   if (msgID)
     deleteCachedMessage(folderID + "/" + msgID);
 }
@@ -1427,27 +1603,59 @@ function onMenuChangeToTrashFolder(event) {
 }
 
 function onMenuLabelNone() {
-  var rowId = document.menuTarget.getAttribute("id").substr(4);
-  var messageId = currentMailbox + "/" + rowId;
-  var urlstr = ApplicationBaseURL + messageId + "/removeAllLabels";
-  triggerAjaxRequest(urlstr, messageFlagCallback,
-                    { mailbox: currentMailbox, msg: rowId, label: null } );
+  var messages = new Array();
+
+  if (document.menuTarget.tagName == "DIV")
+    // Menu called from message content view
+    messages.push(Mailer.currentMessages[Mailer.currentMailbox]);
+  else if (Object.isArray(document.menuTarget))
+    // Menu called from multiple selection in messages list view
+    $(document.menuTarget).collect(function(row) {
+       messages.push(row.getAttribute("id").substr(4));
+      });
+  else
+    // Menu called from one selection in messages list view
+    messages.push(document.menuTarget.getAttribute("id").substr(4));
+  
+  var url = ApplicationBaseURL + Mailer.currentMailbox + "/";
+  messages.each(function(id) {
+      triggerAjaxRequest(url + id + "/removeAllLabels",
+                        messageFlagCallback,
+                        { mailbox: Mailer.currentMailbox, msg: id, label: null } );
+    });  
 }
 
 function _onMenuLabelFlagX(flag) {
-  var flags = document.menuTarget.getAttribute("labels").split(" ");
-
-  var rowId = document.menuTarget.getAttribute("id").substr(4);
-  var messageId = currentMailbox + "/" + rowId;
+  var messages = new Hash();
+
+  if (document.menuTarget.tagName == "DIV")
+    // Menu called from message content view
+    messages.set(Mailer.currentMessages[Mailer.currentMailbox],
+                $('tr#row_' + Mailer.currentMessages[Mailer.currentMailbox]).getAttribute("labels"));
+  else if (Object.isArray(document.menuTarget))
+    // Menu called from multiple selection in messages list view
+    $(document.menuTarget).collect(function(row) {
+       messages.set(row.getAttribute("id").substr(4),
+                    row.getAttribute("labels"));
+      });
+  else
+    // Menu called from one selection in messages list view
+    messages.set(document.menuTarget.getAttribute("id").substr(4),
+                document.menuTarget.getAttribute("labels"));
+  
+  var url = ApplicationBaseURL + Mailer.currentMailbox + "/";
+  messages.keys().each(function(id) {
+      var flags = messages.get(id).split(" ");
+      var operation = "add";
+      
+      if (flags.indexOf("label" + flag) > -1)
+       operation = "remove";
 
-  var operation = "add";
-  if (flags.indexOf("label" + flag) > -1)
-    operation = "remove";
-  var urlstr = (ApplicationBaseURL + messageId
-               + "/" + operation + "Label" + flag);
-  triggerAjaxRequest(urlstr, messageFlagCallback,
-                    { mailbox: currentMailbox, msg: rowId,
-                      label: operation + flag } );
+      triggerAjaxRequest(url + id + "/" + operation + "Label" + flag,
+                        messageFlagCallback,
+                        { mailbox: Mailer.currentMailbox, msg: id,
+                            label: operation + flag } );
+    });
 }
 
 function onMenuLabelFlag1() {
@@ -1482,7 +1690,7 @@ function folderRefreshCallback(http) {
   if (http.readyState == 4
       && isHttpStatus204(http.status)) {
     var oldMailbox = http.callbackData;
-    if (oldMailbox == currentMailbox)
+    if (oldMailbox == Mailer.currentMailbox)
       refreshCurrentFolder();
   }
   else
@@ -1493,7 +1701,7 @@ function messageFlagCallback(http) {
   if (http.readyState == 4
       && isHttpStatus204(http.status)) {
     var data = http.callbackData;
-    if (data["mailbox"] == currentMailbox) {
+    if (data["mailbox"] == Mailer.currentMailbox) {
       var row = $("row_" + data["msg"]);
       var operation = data["label"];
       if (operation) {
@@ -1577,6 +1785,13 @@ function getMenus() {
                                       "mark-menu", "-", null,
                                       onMenuViewMessageSource, null,
                                       null, onMenuDeleteMessage);
+  menus["messagesListMenu"] = new Array(onMenuForwardMessage,
+                                       "-", "moveMailboxMenu",
+                                      "copyMailboxMenu", "label-menu",
+                                      "mark-menu", "-",
+                                       null, null,
+                                       onMenuDeleteMessage);
+  menus["imageMenu"] = new Array(saveImage);
   menus["messageContentMenu"] = new Array(onMenuReplyToSender,
                                          onMenuReplyToAll,
                                          onMenuForwardMessage,
@@ -1606,7 +1821,7 @@ function getMenus() {
   return menus;
 }
 
-addEvent(window, 'load', initMailer);
+FastInit.addOnLoad(initMailer);
 
 function Mailbox(type, name) {
   this.type = type;