]> err.no Git - scalable-opengroupware.org/commitdiff
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1264 d1b88da0-ebda-0310...
authorwolfgang <wolfgang@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Wed, 14 Nov 2007 14:47:39 +0000 (14:47 +0000)
committerwolfgang <wolfgang@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Wed, 14 Nov 2007 14:47:39 +0000 (14:47 +0000)
NEWS
SoObjects/SOGo/SOGoContentObject.h
UI/Contacts/UIxContactFoldersView.m
UI/Templates/SchedulerUI/UIxAttendeesEditor.wox
UI/WebServerResources/SchedulerUI.js
UI/WebServerResources/UIxAttendeesEditor.css
UI/WebServerResources/UIxAttendeesEditor.js
UI/WebServerResources/generic.js
UI/WebServerResources/iefixes.css

diff --git a/NEWS b/NEWS
index 48bf59edfd7a9c859190c61be5a3bc6101491ce7..768a45e0814ec3e01216b21d83b84faa945d4113 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,8 @@
 - support for resizable columns in tables;
 - improved support for multiple selection in tables and lists;
 - improved IE7 and Safari support: attendees selector, email file attachments;
+- updated PrototypeJS to version 1.6.0;
+- improved address completion in attendees selector;
 - changed look of message composition window to Thunderbird 2.0;
 - countless bugfixes;
 
index 62d3fc756a317738a3a011e1192b5c02b5c8a1ce..4fc2c7a8bd5ab1787e11f448b81e5936e2cf821f 100644 (file)
@@ -18,7 +18,6 @@
   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.
 */
-// $Id$
 
 #ifndef __SOGo_SOGoContentObject_H__
 #define __SOGo_SOGoContentObject_H__
index 07d47e4478431820e13e42606d32386af0754f1e..a4f7b1a44a298ad553c93ceccf4500ea7ec10dda 100644 (file)
@@ -35,6 +35,7 @@
 #import <SoObjects/SOGo/LDAPUserManager.h>
 #import <SoObjects/SOGo/SOGoPermissions.h>
 #import <SoObjects/SOGo/SOGoUser.h>
+#import <SoObjects/SOGo/NSArray+Utilities.h>
 #import <SoObjects/SOGo/NSString+Utilities.h>
 #import <SoObjects/Contacts/SOGoContactFolders.h>
 #import <SoObjects/Contacts/SOGoContactFolder.h>
 {
   WOResponse *response;
   NSEnumerator *contacts;
-  NSString *responseString, *email;
+  NSString *email;
   NSDictionary *contact;
+  NSMutableArray *formattedContacts;
+  NSMutableDictionary *formattedContact; 
 
   response = [context response];
 
       [response setStatus: 200];
       contacts = [results objectEnumerator];
       contact = [contacts nextObject];
-      if (contact)
+      formattedContacts = [[NSMutableArray alloc] initWithCapacity: [results count]];
+      while (contact)
        {
          email = [contact objectForKey: @"c_email"];
          if ([email length])
            {
-             responseString = [NSString stringWithFormat: @"%@:%@:%@",
-                                        [contact objectForKey: @"c_uid"],
-                                        [contact objectForKey: @"cn"],
-                                        email];
-//       [response setHeader: @"text/plain; charset=iso-8859-1"
-//                 forKey: @"Content-Type"];
-             [response appendContentString: responseString];
+             formattedContact = [NSMutableDictionary dictionary];
+             [formattedContact setObject: [contact objectForKey: @"c_uid"]
+                               forKey: @"uid"];
+             [formattedContact setObject: [contact objectForKey: @"cn"]
+                               forKey: @"name"];
+             [formattedContact setObject: email
+                               forKey: @"email"];
+             [formattedContacts addObject: formattedContact];
            }
-//       contact = [contacts nextObject];
+         contact = [contacts nextObject];
        }
+      [response appendContentString: [formattedContacts jsonRepresentation]];
+      [formattedContacts release];
     }
   else
     [response setStatus: 404];
index 80ecdd083adbc5d3c104068414322d8f06517e32..8895bcafcbe81927e64e507a9f3eb711922cad59 100644 (file)
@@ -11,6 +11,9 @@
   const:toolbar="none"
   const:popup="YES"
   const:jsFiles="skycalendar.js">
+  <div class="menu" id="attendeesMenu">
+    <ul></ul>
+  </div>
   <div id="attendeesView">
     <div id="freeBusyViewButtons">
       <var:string label:value="Suggest time slot:"/>
index 05ded9b279cdee640609bea6512f50d56893ce54..d68fa0c7952aaaafc60253f7b7767411a1557492 100644 (file)
@@ -32,10 +32,13 @@ function newEvent(sender, type) {
    if (!hour)
       hour = sender.getAttribute("hour");
    var folder = getSelectedFolder();
-   var roles = folder.getAttribute("roles").split(",");
    var folderID = folder.getAttribute("id");
-   if ($(roles).indexOf("PublicModifier") < 0)
-     folderID = "/personal";
+   var roles = folder.getAttribute("roles");
+   if (roles) {
+     roles = roles.split(",")
+       if ($(roles).indexOf("PublicModifier") < 0)
+        folderID = "/personal";
+   }
    var urlstr = ApplicationBaseURL + folderID + "/new" + type;
    var params = new Array();
    if (day)
index 67156317a60d2beaf820dd5b90b11c1626e1235e..48873f787b93eee9486287b9d25eb4b7ee2761d2 100644 (file)
@@ -1,3 +1,7 @@
+DIV#attendeesMenu
+{ overflow: auto;
+  overflow-x: hidden; }
+
 DIV#attendeesView
 { position: absolute;
   left: 1em;
index 9cf96023750dc527b7698c471fdf189f55972c37..dff86b27bcb5945abb36ac4bf22496fe00d18785 100644 (file)
@@ -42,6 +42,10 @@ function onContactKeydown(event) {
       running = true;
       requestField = this;
       requestField.setAttribute("modified", "1");
+      if (searchField) {
+       searchField.confirmedValue = null;
+       searchField.uid = null;
+      }
       setTimeout("triggerRequest()", delay);
     }
     else if (this.confirmedValue) {
@@ -67,35 +71,95 @@ function triggerRequest() {
 
 function updateResults(http) {
   if (http.readyState == 4) {
+    var menu = $('attendeesMenu');
+    var list = menu.down("ul");
+
+    searchField = http.callbackData;
+    searchField.hasfreebusy = false;
+
     if (http.status == 200) {
-      var searchField = http.callbackData;
       var start = searchField.value.length;
-      var text = http.responseText.split(":");
-      if (text[0].length > 0)
-        searchField.uid = text[0];
-      else
-        searchField.uid = null;
-      searchField.hasfreebusy = false;
-      var completeEmail = text[1] + " <" + text[2] + ">";
-      if (text[1].substring(0, searchField.value.length).toUpperCase()
-          == searchField.value.toUpperCase())
-        searchField.value = completeEmail;
-      else {
-        searchField.value += ' >> ' + completeEmail;
+      var data = http.responseText.evalJSON(true);
+      if (data.length > 1) {
+       $(list.childNodesWithTag("li")).each(function(item) {
+           item.remove();
+         });
+       
+       // Populate popup menu
+       for (var i = 0; i < data.length; i++) {
+         var contact = data[i];
+         var completeEmail = contact["name"] + " <" + contact["email"] + ">";
+         var node = document.createElement("li");
+         list.appendChild(node);
+         node.uid = contact["uid"];
+         node.appendChild(document.createTextNode(completeEmail));
+         $(node).observe("mousedown", onAttendeeResultClick);
+       }
+
+       // Show popup menu
+       var offset;
+       if (isSafari())
+         offset = Position.positionedOffset(searchField);
+       else
+         offset = Position.cumulativeOffset(searchField);
+       var top = offset[1] + node.offsetHeight + 3;
+       var height = 'auto';
+       if (data.length > 5) {
+         height = 5 * node.getHeight() + 'px';
+       }
+       menu.setStyle({ top: top + "px",
+             left: offset[0] + "px",
+             height: height,
+             visibility: "visible"  });
+       menu.scrollTop = 0;
+
+       document.currentPopupMenu = menu;
+       $(document.body).observe("click", onBodyClickMenuHandler);
       }
-      searchField.confirmedValue = completeEmail;
-      if (searchField.focussed) {
-        var end = searchField.value.length;
-       $(searchField).selectText(start, end);
+      else {
+       if (document.currentPopupMenu)
+         hideMenu(document.currentPopupMenu);
+
+       if (data.length == 1) {
+         var contact = data[0];
+         if (contact["uid"].length > 0)
+           searchField.uid = contact["uid"];
+         else
+           searchField.uid = null;
+         var completeEmail = contact["name"] + " <" + contact["email"] + ">";
+         if (contact["name"].substring(0, searchField.value.length).toUpperCase()
+             == searchField.value.toUpperCase())
+           searchField.value = completeEmail;
+         else {
+           searchField.value += ' >> ' + completeEmail;
+         }
+         searchField.confirmedValue = completeEmail;
+         if (searchField.focussed) {
+           var end = searchField.value.length;
+           $(searchField).selectText(start, end);
+         }
+         else
+           searchField.value = contact["name"];
+       }
       }
-      else
-        searchField.value = text[1];
     }
+    else
+      if (document.currentPopupMenu)
+       hideMenu(document.currentPopupMenu);
     running = false;
     document.contactLookupAjaxRequest = null;
   }
 }
 
+function onAttendeeResultClick(event) {
+  if (searchField) {
+    searchField.uid = this.uid;
+    searchField.value = this.firstChild.nodeValue.trim();
+    searchField.confirmedValue = searchField.value;
+    searchField.blur(); // triggers checkAttendee function call
+  }
+}
+
 function UIDLookupCallback(http) {
   if (http.readyState == 4) {
     if (http.status == 200) {
@@ -198,14 +262,21 @@ function newAttendee(event) {
   
    var input = $(newRow.cells[0]).childNodesWithTag("input")[0];
    input.setAttribute("autocomplete", "off");
-   Event.observe(input, "blur", checkAttendee.bindAsEventListener(input));
    Event.observe(input, "keydown", onContactKeydown.bindAsEventListener(input));
+   Event.observe(input, "blur", checkAttendee.bindAsEventListener(input));
 
    input.focussed = true;
    input.activate();
 }
 
 function checkAttendee() {
+  if (document.currentPopupMenu && !this.confirmedValue) {
+    // Hack for IE7; blur event is triggered on input field when
+    // selecting a menu item
+    var visible = $(document.currentPopupMenu).getStyle('visibility') != 'hidden';
+    if (visible)
+      return;
+  }
   this.focussed = false;
   var th = this.parentNode.parentNode;
   var tbody = th.parentNode;
@@ -541,4 +612,4 @@ function onFreeBusyLoadHandler() {
    initializeFreebusys();
 }
 
-addEvent(window, 'load', onFreeBusyLoadHandler);
+document.observe("dom:loaded", onFreeBusyLoadHandler);
index ea96808e2c4679ec7de815d64dcecb10c73ab9e0..96c4b00368cb81106491aff8bf5f07291f7e9648 100644 (file)
@@ -576,7 +576,7 @@ function popupMenu(event, menuId, target) {
 
   document.currentPopupMenu = popup;
 
-  Event.observe(document.body, "click", onBodyClickMenuHandler);
+  $(document.body).observe("click", onBodyClickMenuHandler);
 
   preventDefault(event);
 }
@@ -600,7 +600,7 @@ function getParentMenu(node) {
 
 function onBodyClickMenuHandler(event) {
   hideMenu(document.currentPopupMenu);
-  Event.stopObserving(document.body, "click", onBodyClickMenuHandler);
+  document.body.stopObserving("click", onBodyClickMenuHandler);
 
   if (event)
     preventDefault(event);
@@ -615,15 +615,12 @@ function hideMenu(menuNode) {
   }
 
   menuNode.setStyle({ visibility: "hidden" });
-  //   menuNode.hide();
   if (menuNode.parentMenuItem) {
-    Event.stopObserving(menuNode.parentMenuItem, "mouseover",
-                       onMouseEnteredSubmenu);
-    Event.stopObserving(menuNode, "mouseover", onMouseEnteredSubmenu);
-    Event.stopObserving(menuNode.parentMenuItem, "mouseout", onMouseLeftSubmenu);
-    Event.stopObserving(menuNode, "mouseout", onMouseLeftSubmenu);
-    Event.stopObserving(menuNode.parentMenu, "mouseover",
-                       onMouseEnteredParentMenu);
+    menuNode.parentMenuItem.stopObserving("mouseover",onMouseEnteredSubmenu);
+    menuNode.stopObserving("mouseover", onMouseEnteredSubmenu);
+    menuNode.parentMenuItem.stopObserving("mouseout", onMouseLeftSubmenu);
+    menuNode.stopObserving("mouseout", onMouseLeftSubmenu);
+    menuNode.parentMenu.stopObserving("mouseover", onMouseEnteredParentMenu);
     $(menuNode.parentMenuItem).removeClassName("submenu-selected");
     menuNode.parentMenuItem.mouseInside = false;
     menuNode.parentMenuItem = null;
@@ -632,18 +629,7 @@ function hideMenu(menuNode) {
     menuNode.parentMenu = null;
   }
 
-  if (document.createEvent) { // Safari & Mozilla
-    var onhideEvent;
-    if (isSafari())
-      onhideEvent = document.createEvent("UIEvents");
-    else
-      onhideEvent = document.createEvent("Events");
-    onhideEvent.initEvent("mousedown", false, true);
-    menuNode.dispatchEvent(onhideEvent);
-  }
-  else if (document.createEventObject) { // IE
-    menuNode.fireEvent("onmousedown");
-  }
+  $(menuNode).fire("mousedown");
 }
 
 function onMenuEntryClick(event) {
@@ -673,8 +659,8 @@ function initLogConsole() {
   var logConsole = $("logConsole");
   if (logConsole) {
     logConsole.highlighted = false;
-    Event.observe(logConsole, "dblclick", onLogDblClick, false);
-    logConsole.innerHTML = "";
+    logConsole.observe("dblclick", onLogDblClick, false);
+    logConsole.update();
     Event.observe(window, "keydown", onBodyKeyDown);
   }
 }
@@ -776,15 +762,11 @@ function popupSubmenu(event) {
       menuLeft = parentNode.offsetLeft - submenuNode.offsetWidth + 3;
 
     this.mouseInside = true;
-    Event.observe(this, "mouseover",
-                 onMouseEnteredSubmenu.bindAsEventListener(this));
-    Event.observe(submenuNode, "mouseover",
-                 onMouseEnteredSubmenu.bindAsEventListener(submenuNode));
-    Event.observe(this, "mouseout", onMouseLeftSubmenu.bindAsEventListener(this));
-    Event.observe(submenuNode, "mouseout",
-                 onMouseLeftSubmenu.bindAsEventListener(submenuNode));
-    Event.observe(parentNode, "mouseover",
-                 onMouseEnteredParentMenu.bindAsEventListener(parentNode));
+    this.observe("mouseover", onMouseEnteredSubmenu);
+    submenuNode.observe("mouseover", onMouseEnteredSubmenu);
+    this.observe("mouseout", onMouseLeftSubmenu);
+    submenuNode.observe("mouseout", onMouseLeftSubmenu);
+    parentNode.observe("mouseover", onMouseEnteredParentMenu);
     $(this).addClassName("submenu-selected");
     submenuNode.setStyle({ top: menuTop + "px",
                           left: menuLeft + "px",
@@ -829,7 +811,7 @@ function popupSearchMenu(event) {
          visibility: "visible" });
   
     document.currentPopupMenu = popup;
-    Event.observe(document.body, "click", onBodyClickMenuHandler);
+    $(document.body).observe("click", onBodyClickMenuHandler);
   }
 }
 
@@ -865,17 +847,12 @@ function configureSearchField() {
 
   if (!searchValue) return;
 
-  Event.observe(searchValue, "mousedown",
-               onSearchMouseDown.bindAsEventListener(searchValue));
-  Event.observe(searchValue, "click",
-               popupSearchMenu.bindAsEventListener(searchValue));
-  Event.observe(searchValue, "blur",
-               onSearchBlur.bindAsEventListener(searchValue));
-  Event.observe(searchValue, "focus",
-               onSearchFocus.bindAsEventListener(searchValue));
-  Event.observe(searchValue, "keydown",
-               onSearchKeyDown.bindAsEventListener(searchValue));
-
+  searchValue.observe("click", popupSearchMenu);
+  searchValue.observe("blur", onSearchBlur);
+  searchValue.observe("focus", onSearchFocus);
+  searchValue.observe("keydown", onSearchKeyDown);
+  searchValue.observe("mousedown", onSearchMouseDown);
+  
   if (!searchOptions) return;
    
   // Set the checkmark to the first option
@@ -975,7 +952,7 @@ function popupToolbarMenu(node, menuId) {
        visibility: "visible" });
 
   document.currentPopupMenu = popup;
-  Event.observe(document.body, "click", onBodyClickMenuHandler);
+  $(document.body).observe("click", onBodyClickMenuHandler);
 }
 
 /* contact selector */
@@ -1099,10 +1076,8 @@ function initTabs() {
       if (currentNode.tagName == 'LI') {
        if (!firstTab)
          firstTab = i;
-       Event.observe(currentNode, "mousedown",
-                     onTabMouseDown.bindAsEventListener(currentNode));
-       Event.observe(currentNode, "click",
-                     onTabClick.bindAsEventListener(currentNode));
+       $(currentNode).observe("mousedown", onTabMouseDown);
+       $(currentNode).observe("click", onTabClick);
        //$(currentNode.getAttribute("target")).hide();
       }
     }
@@ -1132,9 +1107,7 @@ function initMenu(menuDIV, callbacks) {
   var lis = $(menuDIV.childNodesWithTag("ul")[0]).childNodesWithTag("li");
   for (var j = 0; j < lis.length; j++) {
     var node = $(lis[j]);
-    Event.observe(node, "mousedown",
-                 listRowMouseDownHandler.bindAsEventListener(node),
-                 false);
+    node.observe("mousedown", listRowMouseDownHandler, false);
     var callback = callbacks[j];
     if (callback) {
       if (typeof(callback) == "string") {
@@ -1143,15 +1116,12 @@ function initMenu(menuDIV, callbacks) {
        else {
          node.submenu = callback;
          node.addClassName("submenu");
-         Event.observe(node, "mouseover",
-                       popupSubmenu.bindAsEventListener(node));
+         node.observe("mouseover", popupSubmenu);
        }
       }
       else {
-       Event.observe(node, "mouseup",
-                     onBodyClickMenuHandler);
-       Event.observe(node, "click",
-                     $(callback).bindAsEventListener(node));
+       node.observe("mouseup", onBodyClickMenuHandler);
+       node.observe("click", callback);
       }
     }
     else
@@ -1349,7 +1319,7 @@ function onLoadHandler(event) {
   var progressImage = $("progressIndicator");
   if (progressImage)
     progressImage.parentNode.removeChild(progressImage);
-  Event.observe(document.body, "contextmenu", onBodyClickContextMenu);
+  $(document.body).observe("contextmenu", onBodyClickContextMenu);
 }
 
 function onBodyClickContextMenu(event) {
@@ -1360,8 +1330,8 @@ function configureSortableTableHeaders(table) {
   var headers = $(table).getElementsByClassName("sortableTableHeader");
   for (var i = 0; i < headers.length; i++) {
     var header = headers[i];
-    Event.observe(header, "click", onHeaderClick.bindAsEventListener(header))
-      }
+    $(header).observe("click", onHeaderClick);
+  }
 }
 
 function onLinkBannerClick() {
@@ -1384,13 +1354,13 @@ function configureLinkBanner() {
   if (linkBanner) {
     var anchors = linkBanner.childNodesWithTag("a");
     for (var i = 1; i < 3; i++) {
-      Event.observe(anchors[i], "mousedown", listRowMouseDownHandler);
-      Event.observe(anchors[i], "click", onLinkBannerClick);
+      $(anchors[i]).observe("mousedown", listRowMouseDownHandler);
+      $(anchors[i]).observe("click", onLinkBannerClick);
     }
-    Event.observe(anchors[4], "mousedown", listRowMouseDownHandler);
-    Event.observe(anchors[4], "click", onPreferencesClick);
+    $(anchors[4]).observe("mousedown", listRowMouseDownHandler);
+    $(anchors[4]).observe("click", onPreferencesClick);
     if (anchors.length > 5)
-      Event.observe(anchors[5], "click", toggleLogConsole);
+      $(anchors[5]).observe("click", toggleLogConsole);
   }
 }
 
@@ -1432,7 +1402,7 @@ function onFinalLoadHandler(event) {
     safetyNet.parentNode.removeChild(safetyNet);
 }
 
-addEvent(window, 'load', onLoadHandler);
+document.observe("dom:loaded", onLoadHandler);
 
 function parent$(element) {
   return this.opener.document.getElementById(element);
index 412621b2603462bd048a92cd3f6ada189077ac46..3ee824937cff1c227ba2bc2b12ee74762655e327 100644 (file)
@@ -50,6 +50,10 @@ SPAN.content > INPUT.textField
 
 /* UIxAttendeesEditor */
 
+DIV#attendeesMenu
+{ overflow: scroll;
+  overflow-x: hidden; }
+
 DIV#freeBusyView
 { border-bottom: 1px solid #fff;
   border-right: 1px solid #fff;