]> err.no Git - scalable-opengroupware.org/blobdiff - UI/WebServerResources/ContactsUI.js
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1305 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / UI / WebServerResources / ContactsUI.js
index b0333f8a4a9c198e439036584eb9155ad9612cb7..21c9872f293df3add7507a16c1b3451bcb4e6d00 100644 (file)
@@ -1,69 +1,10 @@
-/*
-  Copyright (C) 2005 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-/* JavaScript for SOGo Mailer */
-
-/*
-  DOM ids available in mail list view:
-    row_$msgid
-    div_$msgid
-    readdiv_$msgid
-    unreaddiv_$msgid
-
-  Window Properties:
-    width, height
-    bool: resizable, scrollbars, toolbar, location, directories, status,
-          menubar, copyhistory
-*/
+/* JavaScript for SOGoContacts */
 
 var cachedContacts = new Array();
-var currentContactFolder = '';
-var currentFolderIsExternal = false;
-var contactSelectorAction = 'addressbooks-contacts';
+var currentContactFolder = null;
 
-function openContactWindow(sender, url) {
-  var msgWin = window.open(url, null, "width=545,height=545,resizable=0");
-  msgWin.focus();
-}
-
-function clickedUid(sender, contactuid) {
-  resetSelection(window);
-  openContactWindow(sender, contactuid,
-                    CurrentContactFolderURL()
-                    + "/" + contactuid + "/edit");
-  return true;
-}
-
-function doubleClickedUid(sender, contactuid) {
-  alert("DOUBLE Clicked " + contactuid);
-
-  return false;
-}
-
-function toggleMailSelect(sender) {
-  var row;
-  row = $(sender.name);
-  row.className = sender.checked ? "tableview_selected" : "tableview";
-}
-
-/* mail editor */
+var usersRightsWindowHeight = 200;
+var usersRightsWindowWidth = 450;
 
 function validateEditorInput(sender) {
   var errortext = "";
@@ -73,71 +14,56 @@ function validateEditorInput(sender) {
   if (field.value == "")
     errortext = errortext + labels.error_missingsubject + "\n";
 
-  if (!UIxRecipientSelectorHasRecipients())
+  if (!hasRecipients())
     errortext = errortext + labels.error_missingrecipients + "\n";
   
   if (errortext.length > 0) {
-    alert(labels.error_validationfailed.decodeEntities() + ":\n"
-          + errortext.decodeEntities());
+    alert(labels.error_validationfailed + ":\n"
+          + errortext);
     return false;
   }
   return true;
 }
 
-function onContactsFolderTreeItemClick(element)
-{
-  var topNode = $('d');
-  var contactsFolder = element.parentNode.getAttribute("dataname");
-
-  if (topNode.selectedEntry)
-    topNode.selectedEntry.deselect();
-  element.select();
-  topNode.selectedEntry = element;
-
-  openContactsFolder(contactsFolder);
-}
+function openContactsFolder(contactsFolder, reload, idx) {
+  if ((contactsFolder && contactsFolder != currentContactFolder)
+      || reload) {
+     currentContactFolder = contactsFolder;
+     var url = URLForFolderID(currentContactFolder) +
+       "/view?noframe=1";
 
-function CurrentContactFolderURL() {
-  return ((currentFolderIsExternal)
-          ? UserFolderURL + "../" + currentContactFolder + "/Contacts/personal"
-          : ApplicationBaseURL + currentContactFolder);
-}
+     var searchValue = search["value"];
+     if (searchValue && searchValue.length > 0)
+       url += ("&search=" + search["criteria"]
+               + "&value=" + escape(searchValue.utf8encode()));
+     var sortAttribute = sorting["attribute"];
+     if (sortAttribute && sortAttribute.length > 0)
+       url += ("&sort=" + sorting["attribute"]
+               + "&asc=" + sorting["ascending"]);
 
-function openContactsFolder(contactsFolder, params, external)
-{
-  if (contactsFolder != currentContactFolder || params) {
+     var selection;
      if (contactsFolder == currentContactFolder) {
         var contactsList = $("contactsList");
         if (contactsList)
            selection = contactsList.getSelectedRowsId();
-        else
-           window.alert("no contactsList");
+//        else
+//           window.alert("no contactsList");
      }
      else
-      selection = null;
-
-    currentContactFolder = contactsFolder;
-    if (external)
-      currentFolderIsExternal = true;
-    else
-      currentFolderIsExternal = false;
-    var url = CurrentContactFolderURL() + "/view?noframe=1&sort=cn&desc=0";
-    if (params)
-      url += '&' + params;
-
-    var selection;
-    if (document.contactsListAjaxRequest) {
-      document.contactsListAjaxRequest.aborted = true;
-      document.contactsListAjaxRequest.abort();
-    }
-    document.contactsListAjaxRequest
-      = triggerAjaxRequest(url, contactsListCallback, selection);
+       selection = null;
+
+     if (document.contactsListAjaxRequest) {
+       document.contactsListAjaxRequest.aborted = true;
+       document.contactsListAjaxRequest.abort();
+     }
+     document.contactsListAjaxRequest
+       = triggerAjaxRequest(url, contactsListCallback, selection);
   }
 }
 
 function openContactsFolderAtIndex(element) {
   var idx = element.getAttribute("idx");
-  var url = CurrentContactFolderURL() + "/view?noframe=1&idx=" + idx;
+  var url = URLForFolderID(currentContactFolder) + "/view?noframe=1&idx=" + idx;
 
   if (document.contactsListAjaxRequest) {
     document.contactsListAjaxRequest.aborted = true;
@@ -147,73 +73,133 @@ function openContactsFolderAtIndex(element) {
     = triggerAjaxRequest(url, contactsListCallback);
 }
 
-function contactsListCallback(http)
-{
-  var div = $("contactsListContent");
+function contactsListCallback(http) {
+  if (http.readyState == 4) {
+    if (http.status == 200) {
+      document.contactsListAjaxRequest = null;
+
+      var table = $("contactsList");
+      if (table) {
+       // Update table
+       var data = http.responseText;
+       var html = data.replace(/^(.*\n)*.*(<table(.*\n)*)$/, "$2");
+       var tbody = table.tBodies[0]; 
+       var tmp = document.createElement('div');
+       $(tmp).update(html);
+       table.replaceChild(tmp.firstChild.tBodies[0], tbody);
+      }
+      else {
+       // Add table (doesn't happen .. yet)
+       var div = $("contactsListContent");
+       div.update(http.responseText);
+       table = $("contactsList");
+       configureSortableTableHeaders(table);
+       TableKit.Resizable.init(table, {'trueResize' : true, 'keepWidth' : true});
+      }
+    
+      if (sorting["attribute"] && sorting["attribute"].length > 0) {
+       var sortHeader;
+       if (sorting["attribute"] == "displayName")
+         sortHeader = $("nameHeader");
+       else if (sorting["attribute"] == "mail")
+         sortHeader = $("mailHeader");
+       else if (sorting["attribute"] == "screenName")
+         sortHeader = $("screenNameHeader");
+       else if (sorting["attribute"] == "org")
+         sortHeader = $("orgHeader");
+       else if (sorting["attribute"] == "phone")
+         sortHeader = $("phoneHeader");
+       else
+         sortHeader = null;
+       
+       if (sortHeader) {
+         var sortImages = $(table.tHead).getElementsByClassName("sortImage");
+         $(sortImages).each(function(item) {
+             item.remove();
+           });
+
+         var sortImage = createElement("img", "messageSortImage", "sortImage");
+         sortHeader.insertBefore(sortImage, sortHeader.firstChild);
+         if (sorting["ascending"])
+           sortImage.src = ResourcesURL + "/title_sortdown_12x12.png";
+         else
+           sortImage.src = ResourcesURL + "/title_sortup_12x12.png";
+       }
+      }
 
-  if (http.readyState == 4
-      && http.status == 200) {
-    document.contactsListAjaxRequest = null;
-    div.innerHTML = http.responseText;
-    var selected = http.callbackData;
-    if (selected) {
-        for (var i = 0; i < selected.length; i++)
-          $(selected[i]).select();
+      var selected = http.callbackData;
+      if (selected) {
+       for (var i = 0; i < selected.length; i++) {
+         var row = $(selected[i]);
+         if (row)
+           row.select();
+       }
+      }
+    }
+    else {
+      var table = $("contactsList");
+      if (table) {
+       var sortImages = $(table.tHead).getElementsByClassName("sortImage");
+       $(sortImages).each(function(item) {
+           item.remove();
+         });
+       var tBody = $(table.tBodies[0]);
+       var length = tBody.rows.length;
+       for (var i = length - 1; i > -1; i--)
+         tBody.removeChild(tBody.rows[i]);
+      }
     }
-    configureSortableTableHeaders();
   }
   else
-    log ("ajax fuckage 1");
+    log ("ajax problem 1: status = " + http.status);
 }
 
-function onContactFoldersContextMenu(event)
-{
+function onContactFoldersContextMenu(event) {
   var menu = $("contactFoldersMenu");
-  menu.addEventListener("hideMenu", onContactFoldersContextMenuHide, false);
-  onMenuClick(event, "contactFoldersMenu");
+  //Event.observe(menu, "hideMenu", onContactFoldersContextMenuHide, false);
+  Event.observe(menu, "mousedown", onContactFoldersContextMenuHide, false);
+  popupMenu(event, "contactFoldersMenu", this);
 
   var topNode = $("contactFolders");
   var selectedNodes = topNode.getSelectedRows();
   topNode.menuSelectedRows = selectedNodes;
   for (var i = 0; i < selectedNodes.length; i++)
-    selectedNodes[i].deselect();
+    $(selectedNodes[i]).deselect();
   topNode.menuSelectedEntry = this;
-  this.select();
+  $(this).select();
 }
 
-function onContactContextMenu(event, element)
-{
+function onContactContextMenu(event, element) { log ("onContactContextMenu");
   var menu = $("contactMenu");
-  menu.addEventListener("hideMenu", onContactContextMenuHide, false);
-  onMenuClick(event, "contactMenu");
+
+  Event.observe(menu, "mousedown", onContactContextMenuHide, false);
+  popupMenu(event, "contactMenu", element);
 
   var topNode = $("contactsList");
   var selectedNodes = topNode.getSelectedRows();
   topNode.menuSelectedRows = selectedNodes;
   for (var i = 0; i < selectedNodes.length; i++)
-    selectedNodes[i].deselect();
+    $(selectedNodes[i]).deselect();
   topNode.menuSelectedEntry = element;
-  element.select();
+  $(element).select();
 }
 
-function onContactContextMenuHide(event)
-{
+function onContactContextMenuHide(event) {
   var topNode = $("contactsList");
 
   if (topNode.menuSelectedEntry) {
-    topNode.menuSelectedEntry.deselect();
+    $(topNode.menuSelectedEntry).deselect();
     topNode.menuSelectedEntry = null;
   }
   if (topNode.menuSelectedRows) {
     var nodes = topNode.menuSelectedRows;
     for (var i = 0; i < nodes.length; i++)
-      nodes[i].select();
+      $(nodes[i]).select();
     topNode.menuSelectedRows = null;
   }
 }
 
-function onContactFoldersContextMenuHide(event)
-{
+function onContactFoldersContextMenuHide(event) {
   var topNode = $("contactFolders");
 
   if (topNode.menuSelectedEntry) {
@@ -228,8 +214,7 @@ function onContactFoldersContextMenuHide(event)
   }
 }
 
-function onFolderMenuHide(event)
-{
+function onFolderMenuHide(event) {
   var topNode = $('d');
 
   if (topNode.menuSelectedEntry) {
@@ -240,8 +225,7 @@ function onFolderMenuHide(event)
     topNode.selectedEntry.select();
 }
 
-function loadContact(idx)
-{
+function loadContact(idx) {
   if (document.contactAjaxRequest) {
     document.contactAjaxRequest.aborted = true;
     document.contactAjaxRequest.abort();
@@ -252,15 +236,14 @@ function loadContact(idx)
     div.innerHTML = cachedContacts[currentContactFolder + "/" + idx];
   }
   else {
-    var url = (CurrentContactFolderURL() + "/"
-               + idx + "/view?noframe=1");
+    var url = (URLForFolderID(currentContactFolder)
+              + "/" + idx + "/view?noframe=1");
     document.contactAjaxRequest
       = triggerAjaxRequest(url, contactLoadCallback, idx);
   }
 }
 
-function contactLoadCallback(http)
-{
+function contactLoadCallback(http) {
   var div = $('contactView');
 
   if (http.readyState == 4
@@ -271,7 +254,7 @@ function contactLoadCallback(http)
     div.innerHTML = content;
   }
   else
-    log ("ajax fuckage 2");
+    log ("ajax problem 2: " + http.status);
 }
 
 var rowSelectionCount = 0;
@@ -304,86 +287,104 @@ function moveTo(uri) {
 }
 
 /* contact menu entries */
-function onContactRowClick(event, node)
-{
+function onContactRowClick(event, node) {
   loadContact(node.getAttribute('id'));
 
   return onRowClick(event);
 }
 
-function onContactRowDblClick(event, node)
-{
+function onContactRowDblClick(event, node) {
   var contactId = node.getAttribute('id');
 
-  openContactWindow(null,
-                    CurrentContactFolderURL()
-                    + "/" + contactId + "/edit");
+  openContactWindow(URLForFolderID(currentContactFolder)
+                    + "/" + contactId + "/edit", contactId);
 
   return false;
 }
 
-function onMenuEditContact(event, node)
-{
-  var node = getParentMenu(node).menuTarget.parentNode;
-  var contactId = node.getAttribute('id');
-
-  openContactWindow(null,
-                    CurrentContactFolderURL()
-                    + "/" + contactId + "/edit");
+function onMenuEditContact(event) {
+  var contactId = document.menuTarget.getAttribute('id');
 
-  return false;
+  openContactWindow(URLForFolderID(currentContactFolder)
+                    + "/" + contactId + "/edit", contactId);
 }
 
-function onMenuWriteToContact(event, node)
-{
-  var node = getParentMenu(node).menuTarget.parentNode;
-  var contactId = node.getAttribute('id');
+function onMenuWriteToContact(event) {
+  var contactId = document.menuTarget.getAttribute('id');
+  var contactRow = $(contactId);
+  var emailCell = contactRow.down('td', 1);
 
-  openMailComposeWindow(CurrentContactFolderURL()
-                        + "/" + contactId + "/write");
+  if (!emailCell.firstChild) { // .nodeValue is the contact email address
+    window.alert(labels["The selected contact has no email address."]);
+    return false;
+  }
 
-  return false;
-}
+  openMailComposeWindow(ApplicationBaseURL + currentContactFolder
+                       + "/" + contactId + "/write");
 
-function onMenuDeleteContact(event, node)
-{
-  uixDeleteSelectedContacts(node);
+  if (document.body.hasClassName("popup"))
+    window.close();
+}
 
-  return false;
+function onMenuDeleteContact(event) {
+  uixDeleteSelectedContacts(this);
 }
 
-function onToolbarEditSelectedContacts(event)
-{
+function onToolbarEditSelectedContacts(event) {
   var contactsList = $('contactsList');
   var rows = contactsList.getSelectedRowsId();
 
+  if (rows.length == 0) {
+    window.alert(labels["Please select a contact."]);
+    return false;
+  }
+
   for (var i = 0; i < rows.length; i++) {
-    openContactWindow(null,
-                      CurrentContactFolderURL()
-                      + "/" + rows[i] + "/edit");
+    openContactWindow(URLForFolderID(currentContactFolder)
+                      + "/" + rows[i] + "/edit", rows[i]);
   }
 
   return false;
 }
 
-function onToolbarWriteToSelectedContacts(event)
-{
+function onToolbarWriteToSelectedContacts(event) {
   var contactsList = $('contactsList');
   var rows = contactsList.getSelectedRowsId();
+  var rowsWithEmail = 0;
+
+  if (rows.length == 0) {
+    openMailComposeWindow(ApplicationBaseURL + "Mail/compose");
+    return false;
+  }
 
-  for (var i = 0; i < rows.length; i++)
-    openMailComposeWindow(CurrentContactFolderURL()
-                          + "/" + rows[i] + "/write");
+  for (var i = 0; i < rows.length; i++) {
+    var emailCell = $(rows[i]).down('td', 1);
+    if (emailCell.firstChild) { // .nodeValue is the contact email address
+      rowsWithEmail++;
+      openMailComposeWindow(ApplicationBaseURL + currentContactFolder
+                           + "/" + rows[i] + "/write");
+    }
+  }
+
+  if (rowsWithEmail == 0) {
+    window.alert(labels["The selected contact has no email address."]);
+  }
+  else if (document.body.hasClassName("popup"))
+    window.close();
 
   return false;
 }
 
-function uixDeleteSelectedContacts(sender)
-{
+function uixDeleteSelectedContacts(sender) {
   var failCount = 0;
   var contactsList = $('contactsList');
   var rows = contactsList.getSelectedRowsId();
 
+  if (rows.length == 0) {
+    window.alert(labels["Please select a contact."]);
+    return false;
+  }
+
   var contactView = $('contactView');
   contactView.innerHTML = '';
 
@@ -392,7 +393,7 @@ function uixDeleteSelectedContacts(sender)
     
     /* send AJAX request (synchronously) */
     
-    url = (CurrentContactFolderURL() + "/"
+    url = (URLForFolderID(currentContactFolder) + "/"
            + rows[i] + "/delete");
     http = createHTTPClient();
     http.open("POST", url, false /* not async */);
@@ -412,7 +413,7 @@ function uixDeleteSelectedContacts(sender)
   }
 
   if (failCount > 0)
-    alert("Could not delete " + failCount + " messages!");
+    alert("Could not delete the selected contacts!");
   
   return false;
 }
@@ -421,264 +422,240 @@ function newEmailTo(sender) {
   var mailto = sanitizeMailTo(sender.parentNode.parentNode.menuTarget.innerHTML);
 
   if (mailto.length > 0)
-    {
-      w = window.open("compose?mailto=" + mailto,
-                     "SOGo_compose",
-                     "width=680,height=520,resizable=1,scrollbars=1,toolbar=0," +
-                     "location=0,directories=0,status=0,menubar=0,copyhistory=0");
-      w.focus();
-    }
+    openMailComposeWindow("compose?mailto=" + mailto);
 
   return false; /* stop following the link */
 }
 
-function onHeaderClick(event)
-{
-  if (document.contactsListAjaxRequest) {
-    document.contactsListAjaxRequest.aborted = true;
-    document.contactsListAjaxRequest.abort();
-  }
-  url = CurrentContactFolderURL() + "/" + this.link;
-  if (!this.link.match(/noframe=/))
-    url += "&noframe=1";
-  document.contactsListAjaxRequest
-    = triggerAjaxRequest(url, contactsListCallback);
+function onHeaderClick(event) {
+   var headerId = this.getAttribute("id");
+   var newSortAttribute;
+   if (headerId == "nameHeader")
+      newSortAttribute = "displayName";
+   else if (headerId == "mailHeader")
+      newSortAttribute = "mail";
+   else if (headerId == "screenNameHeader")
+      newSortAttribute = "screenName";
+   else if (headerId == "orgHeader")
+      newSortAttribute = "org";
+   else if (headerId == "phoneHeader")
+      newSortAttribute = "phone";
 
-  event.preventDefault();
-}
+   if (sorting["attribute"] == newSortAttribute)
+      sorting["ascending"] = !sorting["ascending"];
+   else {
+      sorting["attribute"] = newSortAttribute;
+      sorting["ascending"] = true;
+   }
+
+   refreshCurrentFolder();
 
-function registerDraggableMessageNodes()
-{
-  log ("can we drag...");
+   Event.stop(event);
 }
 
 function newContact(sender) {
-  openContactWindow(sender,
-                    CurrentContactFolderURL() + "/new");
+  openContactWindow(URLForFolderID(currentContactFolder) + "/new");
 
   return false; /* stop following the link */
 }
 
-function onFolderSelectionChange()
-{
-  var folderList = $("contactFolders");
-  var nodes = folderList.getSelectedNodes();
-  $("contactView").innerHTML = '';
-
-  if (nodes[0].hasClassName("denied")) {
-    var div = $("contactsListContent");
-    div.innerHTML = "";
-  }
-  else {
-    var newFolder;
-    var externalFolder = nodes[0].getAttribute("external-addressbook");
-    if (externalFolder)
-      newFolder = externalFolder;
-    else
-      newFolder = nodes[0].getAttribute("id");
-
-    openContactsFolder(newFolder, null, externalFolder);
-  }
-}
-
-function onSearchFormSubmit()
-{
-  var searchValue = $("searchValue");
-
-  openContactsFolder(currentContactFolder, "search=" + searchValue.value);
-
-  return false;
-}
-
-function onConfirmContactSelection(tag)
-{
-  var folderLi = $(currentContactFolder);
-  var currentContactFolderName = folderLi.innerHTML;
-  var selectorList = null;
-  var initialValues = null;
-
-  if (selector)
-    {
+function onFolderSelectionChange() {
+   var folderList = $("contactFolders");
+   var nodes = folderList.getSelectedNodes();
+   $("contactView").innerHTML = '';
+  
+   if (nodes[0].hasClassName("denied")) {
+      var div = $("contactsListContent");
+      div.update();
+   }
+   else {
+      search = {};
+      sorting = {};
+      $("searchValue").value = "";
+      initCriteria();
+      openContactsFolder(nodes[0].getAttribute("id"));
+   }
+}
+
+function refreshCurrentFolder() {
+  openContactsFolder(currentContactFolder, true);
+}
+
+function onConfirmContactSelection(event) {
+   var tag = this.getAttribute("name");
+   var folderLi = $(currentContactFolder);
+   var currentContactFolderName = folderLi.innerHTML;
+   var selectorList = null;
+   var initialValues = null;
+
+   if (selector) {
       var selectorId = selector.getAttribute("id");
       selectorList = opener.window.document.getElementById('uixselector-'
                                                            + selectorId
                                                            + '-uidList');
       initialValues = selectorList.value;
-    }
+   }
 
-  var contactsList = $("contactsList");
-  var rows = contactsList.getSelectedRows();
-  for (i = 0; i < rows.length; i++) {
-    var cid = rows[i].getAttribute("contactid");
-    var cname = '' + rows[i].getAttribute("contactname");
-    var email = '' + rows[i].cells[1].innerHTML;
-    opener.window.addContact(tag, currentContactFolderName + '/' + cname,
-                             cid, cname, email);
-  }
+   var contactsList = $("contactsList");
+   var rows = contactsList.getSelectedRows();
+   for (i = 0; i < rows.length; i++) {
+      var cid = rows[i].getAttribute("contactid");
+      var cname = '' + rows[i].getAttribute("contactname");
+      var email = '' + rows[i].cells[1].innerHTML;
+      window.opener.addContact(tag, currentContactFolderName + '/' + cname,
+                              cid, cname, email);
+   }
 
-  if (selector && selector.changeNotification
-      && selectorList.value != initialValues)
-    selector.changeNotification("addition");
+   if (selector && selector.changeNotification
+       && selectorList.value != initialValues)
+      selector.changeNotification("addition");
 
-  return false;
+   preventDefault(event);
 }
 
-function onConfirmAddressBookSelection() {
-  var folderLi = $(currentContactFolder);
-  var currentContactFolderName = folderLi.innerHTML;
-
-  var selector = window.opener.document.getElementById("contactFolders");
-  var initialValues = selector.getAttribute("additional-addressbooks");
-  if (!initialValues)
-    initialValues = "";
-  var newValues = initialValues;
-
-  var contactsList = $("contactsList");
-  var rows = contactsList.getSelectedRows();
-  for (i = 0; i < rows.length; i++) {
-    var cid = rows[i].getAttribute("contactid");
-    var cname = '' + rows[i].getAttribute("contactname");
-    var email = '' + rows[i].cells[1].innerHTML;
-    var re = new RegExp("(^|,)" + cid + "($|,)");
-    if (!re.test(newValues)) {
-      if (newValues.length)
-        newValues += "," + cid;
-      else
-        newValues = cid;
-    }
-  }
+function onContactMailTo(node) {
+  return openMailTo(node.innerHTML);
+}
 
-  if (newValues != initialValues)
-    window.opener.setTimeout("setAdditionalAddressBooks(\""
-                             + newValues + "\");", 100);
+function refreshContacts(contactId) {
+   refreshCurrentFolder();
+   cachedContacts[currentContactFolder + "/" + contactId] = null;
+   loadContact(contactId);
 
-  return false;
+   return false;
 }
 
-function setAdditionalAddressBooks(additionalAddressBooks) {
-  var urlstr = (ApplicationBaseURL + "/updateAdditionalAddressBooks?ids="
-                + additionalAddressBooks);
-  if (document.addressBooksAjaxRequest) {
-    document.addressBooksAjaxRequest.aborted = true;
-    document.addressBooksAjaxRequest.abort();
-  }
-  document.addressBooksAjaxRequest
-    = triggerAjaxRequest(urlstr,
-                         addressBooksCallback, additionalAddressBooks);
+function onAddressBookNew(event) {
+  createFolder(window.prompt(labels["Name of the Address Book"]),
+              appendAddressBook);
+  preventDefault(event);
 }
 
-function addressBooksCallback(http) {
-  if (http.readyState == 4) {
-    if (http.status == 200) {
-      var ul = $("contactFolders");
+function appendAddressBook(name, folder) {
+  var owner;
+  var result = true;
 
-      var children = ul.childNodesWithTag("li");
-      for (var i = 0; i < children.length; i++)
-        if (children[i].getAttribute("external-addressbook"))
-          ul.removeChild(children[i]);
-
-      ul.setAttribute("additional-addressbooks", http.callbackData);
-      if (http.callbackData.length > 0) {
-        var list = http.callbackData.split(",");
-        var newCode = "";
-        for (var i = 0; i < list.length; i++) {
-          var username = list[i];
-          newCode += ( "<li external-addressbook=\"" + username + "\""
-                       + " onmousedown=\"return false;\""
-                       + " onclick=\"return onRowClick(event);\""
-                       + " oncontextmenu=\"return onContactFolderContextMenu(event);\">" );
-          newCode += ( username + "</li>" );
-        }
-        ul.innerHTML += newCode;
-      }
-    }
-    document.addressBooksAjaxRequest = null;
+  if (folder) {
+    owner = getSubscribedFolderOwner(folder);
+    folder = accessToSubscribedFolder(folder);
   }
   else
-    log ("ajax fuckage 3");
-}
-
-function onContactMailTo(node) {
-  return openMailTo(node.innerHTML);
-}
+    folder = "/" + name;
+  
+  if (!owner)
+    owner = UserLogin;
 
-function refreshContacts(contactId) {
-  openContactsFolder(currentContactFolder, "reload=true", currentFolderIsExternal);
-  cachedContacts[currentContactFolder + "/" + contactId] = null;
-  loadContact(contactId);
+  if ($(folder))
+    result = false;
+  else {
+    var contactFolders = $("contactFolders");
+    var items = contactFolders.childNodesWithTag("li");
+    var li = document.createElement("li");
 
-  return false;
-}
+    // Add the calendar to the proper place
+    var i = getListIndexForFolder(items, owner, name);
+    if (i != items.length) // User is subscribed to other calendars of the same owner
+      contactFolders.insertBefore(li, items[i]);
+    else 
+      contactFolders.appendChild(li);
 
-function onAddressBookNew(event) {
-  var name = window.prompt(labels["Name of the Address Book"].decodeEntities());
-  if (name) {
-    if (document.newAbAjaxRequest) {
-      document.newAbAjaxRequest.aborted = true;
-      document.newAbAjaxRequest.abort();
-    }
-    var url = ApplicationBaseURL + "/newAb?name=" + name;
-    document.newAbAjaxRequest
-       = triggerAjaxRequest(url, newAbCallback, name);
+    li.setAttribute("id", folder);
+    li.setAttribute("owner", owner);
+    li.appendChild(document.createTextNode(name));
+    setEventsOnContactFolder(li);
   }
-  event.preventDefault();
+
+  return result;
 }
 
-function newAbCallback(http) {
+function newFolderCallback(http) {
   if (http.readyState == 4
       && http.status == 201) {
-     var ul = $("contactFolders");
      var name = http.callbackData;
-     var li = document.createElement("li");
-     li.setAttribute("id", "/" + name);
-     li.appendChild(document.createTextNode(name));
-     li.addEventListener("mousedown", listRowMouseDownHandler, false);
-     li.addEventListener("click", onRowClick, false);
-     li.addEventListener("contextmenu", onContactFoldersContextMenu, false);
-     ul.appendChild(li);
+     appendAddressBook(name, "/" + name);
   }
   else
-    log ("ajax fuckage 4:" + http.status);
+    log ("ajax problem 4:" + http.status);
+}
+
+function newUserFolderCallback(folderData) {
+   var folder = $(folderData["folder"]);
+   if (!folder)
+      appendAddressBook(folderData["folderName"], folderData["folder"]);
 }
 
 function onAddressBookAdd(event) {
-  var selector = $("contactFolders");
-  var selectorURL = '?popup=YES&selectorId=contactFolders';
+   openUserFolderSelector(newUserFolderCallback, "contact");
 
-  urlstr = ApplicationBaseURL;
-  if (urlstr[urlstr.length-1] != '/')
-    urlstr += '/';
-  urlstr += ("../../" + UserLogin + "/Contacts/"
-             + contactSelectorAction + selectorURL);
-//   log (urlstr);
-  var w = window.open(urlstr, "Addressbook",
-                      "width=640,height=400,resizable=1,scrollbars=0");
-  w.selector = selector;
-  w.opener = window;
-  w.focus();
+   preventDefault(event);
+}
 
-  event.preventDefault();
+function onFolderUnsubscribeCB(folderId) {
+   var node = $(folderId);
+   node.parentNode.removeChild(node);
+   var personal = $("/personal");
+   personal.select();
+   onFolderSelectionChange();
 }
 
 function onAddressBookRemove(event) {
   var selector = $("contactFolders");
   var nodes = selector.getSelectedNodes();
-  if (nodes.length > 0) {
-    var cid = nodes[0].getAttribute("external-addressbook");
-    if (cid) {
-      var initialValues = selector.getAttribute("additional-addressbooks");
-      var re = new RegExp("(^|,)" + cid + "($|,)");
-      var newValues = initialValues.replace(re, "");
-      if (initialValues != newValues)
-        setAdditionalAddressBooks(newValues);
-      
+  if (nodes.length > 0) { 
+    nodes[0].deselect();
+    var folderId = nodes[0].getAttribute("id");
+    var folderIdElements = folderId.split("_");
+    if (folderIdElements.length > 1)
+      unsubscribeFromFolder(folderId, onFolderUnsubscribeCB, folderId);
+    else {
+      var abId = folderIdElements[0].substr(1);
+      deletePersonalAddressBook(abId);
       var personal = $("/personal");
       personal.select();
       onFolderSelectionChange();
     }
   }
 
-  event.preventDefault();
+  preventDefault(event);
+}
+
+function deletePersonalAddressBook(folderId) {
+  var label
+    = labels["Are you sure you want to delete the selected address book?"];
+  if (window.confirm(label)) {
+    if (document.deletePersonalABAjaxRequest) {
+      document.deletePersonalABAjaxRequest.aborted = true;
+      document.deletePersonalABAjaxRequest.abort();
+    }
+    var url = ApplicationBaseURL + "/" + folderId + "/deleteFolder";
+    document.deletePersonalABAjaxRequest
+      = triggerAjaxRequest(url, deletePersonalAddressBookCallback,
+                          folderId);
+  }
+}
+
+function deletePersonalAddressBookCallback(http) {
+  if (http.readyState == 4) {
+    if (isHttpStatus204(http.status)) {
+      var ul = $("contactFolders");
+       
+      var children = ul.childNodesWithTag("li");
+      var i = 0;
+      var done = false;
+      while (!done && i < children.length) {
+       var currentFolderId = children[i].getAttribute("id").substr(1);
+       if (currentFolderId == http.callbackData) {
+         ul.removeChild(children[i]);
+         done = true;
+       }
+       else
+         i++;
+      }
+    }
+    document.deletePersonalABAjaxRequest = null;
+  }
+  else
+    log ("ajax problem 5: " + http.status);
 }
 
 function configureDragHandles() {
@@ -687,6 +664,7 @@ function configureDragHandles() {
     handle.addInterface(SOGoDragHandlesInterface);
     handle.leftBlock=$("contactFoldersList");
     handle.rightBlock=$("rightPanel");
+    handle.leftMargin = 100;
   }
 
   handle = $("rightDragHandle");
@@ -698,82 +676,171 @@ function configureDragHandles() {
 }
 
 function lookupDeniedFolders() {
-  var rights;
-  var http = createHTTPClient();
-  if (http) {
-    http.url = ApplicationBaseURL + "/checkRights";
-    http.open("GET", http.url, false /* not async */);
-    http.send("");
-    if (http.status == 200
-        && http.responseText.length > 0) {
-      rights = http.responseText.split(",");
-    }
+  var list = $("contactFolders").childNodesWithTag("li");
+  for (var i = 0; i < list.length; i++) {
+     var folderID = list[i].getAttribute("id");
+     var url = URLForFolderID(folderID) + "/canAccessContent";
+     triggerAjaxRequest(url, deniedFoldersLookupCallback, folderID);
   }
+}
 
-  return rights;
+function deniedFoldersLookupCallback(http) {
+   if (http.readyState == 4) {
+      var denied = ! isHttpStatus204(http.status);
+      var entry = $(http.callbackData);
+      if (denied)
+        entry.addClassName("denied");
+      else
+        entry.removeClassName("denied");
+   }
 }
 
 function configureAbToolbar() {
   var toolbar = $("abToolbar");
   var links = toolbar.childNodesWithTag("a");
-  links[0].addEventListener("click", onAddressBookNew, false);
-  links[1].addEventListener("click", onAddressBookAdd, false);
-  links[2].addEventListener("click", onAddressBookRemove, false);
+  Event.observe(links[0], "click", onAddressBookNew, false);
+  Event.observe(links[1], "click", onAddressBookAdd, false);
+  Event.observe(links[2], "click", onAddressBookRemove, false);
 }
 
 function configureContactFolders() {
   var contactFolders = $("contactFolders");
   if (contactFolders) {
-    contactFolders.addEventListener("selectionchange",
-                                    onFolderSelectionChange, false);
+    Event.observe(contactFolders, "mousedown", listRowMouseDownHandler);
+    Event.observe(contactFolders, "click", onFolderSelectionChange);
     var lis = contactFolders.childNodesWithTag("li");
-    for (var i = 0; i < lis.length; i++) {
-      lis[i].addEventListener("mousedown", listRowMouseDownHandler, false);
-      lis[i].addEventListener("click", onRowClick, false);
-      lis[i].addEventListener("contextmenu", onContactFoldersContextMenu, false);
-    }
+    for (var i = 0; i < lis.length; i++)
+      setEventsOnContactFolder(lis[i]);
 
-    var denieds = lookupDeniedFolders();
-    if (denieds) {
-      var start = (lis.length - denieds.length);
-      for (var i = start; i < lis.length; i++) {
-        if (denieds[i-start] == "1")
-          lis[i].removeClassName("denied");
-        else
-          lis[i].addClassName("denied");
-      }
-    }
-    contactFolders.style.visibility = "visible;";
+    lookupDeniedFolders();
+
+    var personalFolder = $("/personal");
+    personalFolder.select();
+    openContactsFolder("/personal");
   }
 }
 
-function onAccessRightsMenuEntryMouseUp(event) {
+function setEventsOnContactFolder(node) {
+   Event.observe(node, "mousedown", listRowMouseDownHandler, false);
+   Event.observe(node, "click", onRowClick, false);
+   Event.observe(node, "contextmenu",
+                onContactFoldersContextMenu.bindAsEventListener(node), false);
+}
+
+function onMenuModify(event) {
   var folders = $("contactFolders");
   var selected = folders.getSelectedNodes()[0];
-  var external = selected.getAttribute("external-addressbook");
-  var title = this.innerHTML;
-  if (external)
-    url = UserFolderURL + "../" + external + "/Contacts/personal/acls";
-  else
-    url = ApplicationBaseURL + selected.getAttribute("id") + "/acls";
 
-  openAclWindow(url, title);
+  if (UserLogin == selected.getAttribute("owner")) {
+    var currentName = selected.innerHTML;
+    var newName = window.prompt(labels["Address Book Name"],
+                               currentName);
+    if (newName && newName.length > 0
+       && newName != currentName) {
+      var url = (URLForFolderID(selected.getAttribute("id"))
+                + "/renameFolder?name=" + escape(newName.utf8encode()));
+      triggerAjaxRequest(url, folderRenameCallback,
+                        {node: selected, name: newName});
+    }
+  } else
+    window.alert(clabels["Unable to rename that folder!"]);
+}
+
+function folderRenameCallback(http) {
+  if (http.readyState == 4) {
+    if (isHttpStatus204(http.status)) {
+      var dict = http.callbackData;
+      dict["node"].innerHTML = dict["name"];
+    }
+  }
 }
 
-function initializeMenus() {
-  var menus = new Array("contactFoldersMenu", "contactMenu", "searchMenu");
-  initMenusNamed(menus);
+function onMenuSharing(event) {
+  if ($(this).hasClassName("disabled"))
+    return;
+
+   var folders = $("contactFolders");
+   var selected = folders.getSelectedNodes()[0];
+   var owner = selected.getAttribute("owner");
+   if (owner == "nobody")
+     window.alert(clabels["The user rights cannot be"
+                         + " edited for this object!"]);
+   else {
+     var title = this.innerHTML;
+     var url = URLForFolderID(selected.getAttribute("id"));
 
-  var menuEntry = $("accessRightsMenuEntry");
-  menuEntry.addEventListener("mouseup", onAccessRightsMenuEntryMouseUp, false);
+     openAclWindow(url + "/acls", title);
+   }
 }
 
-var initContacts = {
-  handleEvent: function (event) {
-    configureAbToolbar();
-    configureContactFolders();
-//     initDnd();
+function onContactFoldersMenuPrepareVisibility() {
+  var folders = $("contactFolders");
+  var selected = folders.getSelectedNodes();  
+
+  if (selected.length > 0) {
+    var folderOwner = selected[0].getAttribute("owner");
+    var modifyOption = $(this).down("ul").childElements().first();
+    var sharingOption = $(this).down("ul").childElements().last();
+    // Disable the "Sharing" and "Modify" options when address book
+    // is not owned by user
+    if (folderOwner == UserLogin || IsSuperUser) {
+      modifyOption.removeClassName("disabled");
+      sharingOption.removeClassName("disabled");
+    }
+    else {
+      modifyOption.addClassName("disabled");
+      sharingOption.addClassName("disabled");
+    }
   }
 }
 
-window.addEventListener("load", initContacts, false);
+function getMenus() {
+   var menus = {};
+   menus["contactFoldersMenu"] = new Array(onMenuModify, "-", null,
+                                          null, "-", null, "-",
+                                          onMenuSharing);
+   menus["contactMenu"] = new Array(onMenuEditContact, "-",
+                                   onMenuWriteToContact, null, "-",
+                                   onMenuDeleteContact);
+   menus["searchMenu"] = new Array(setSearchCriteria);
+   
+   var contactFoldersMenu = $("contactFoldersMenu");
+   if (contactFoldersMenu)
+     contactFoldersMenu.prepareVisibility = onContactFoldersMenuPrepareVisibility;
+   
+   return menus;
+}
+
+function configureSelectionButtons() {
+   var container = $("contactSelectionButtons");
+   if (container) {
+      var buttons = container.childNodesWithTag("input");
+      for (var i = 0; i < buttons.length; i++)
+       Event.observe(buttons[i], "click",
+                     onConfirmContactSelection.bindAsEventListener(buttons[i]));
+   }
+}
+
+function initContacts(event) {
+   if (!document.body.hasClassName("popup")) {
+     configureAbToolbar();
+   }
+   else
+     configureSelectionButtons();
+   configureContactFolders();
+//     initDnd();
+
+   var table = $("contactsList");
+   if (table) {
+     // Initialize contacts table
+     table.multiselect = true;
+     configureSortableTableHeaders(table);
+     TableKit.Resizable.init(table, {'trueResize' : true, 'keepWidth' : true});
+   }
+
+   // Default sort options
+   sorting["attribute"] = "displayName";
+   sorting["ascending"] = true;
+}
+
+FastInit.addOnLoad(initContacts);