[Svn] r3345 - in branches/devel-threads: . program/js program/localization/en_US program/steps/mail skins/default skins/default/images skins/default/images/icons skins/default/includes skins/default/templates

trac at roundcube.net trac at roundcube.net
Wed Mar 10 14:19:07 CET 2010


Author: thomasb
Date: 2010-03-10 07:19:07 -0600 (Wed, 10 Mar 2010)
New Revision: 3345

Modified:
   branches/devel-threads/THREADS
   branches/devel-threads/program/js/app.js
   branches/devel-threads/program/localization/en_US/labels.inc
   branches/devel-threads/program/steps/mail/func.inc
   branches/devel-threads/skins/default/common.css
   branches/devel-threads/skins/default/functions.js
   branches/devel-threads/skins/default/ie6hacks.css
   branches/devel-threads/skins/default/images/icons/columnpicker.gif
   branches/devel-threads/skins/default/images/messageactions.gif
   branches/devel-threads/skins/default/images/messageactions.png
   branches/devel-threads/skins/default/includes/messagemenu.html
   branches/devel-threads/skins/default/mail.css
   branches/devel-threads/skins/default/templates/mail.html
Log:
Generate message list only client-side + visual improvements to (threaded) mail view

Modified: branches/devel-threads/THREADS
===================================================================
--- branches/devel-threads/THREADS	2010-03-09 17:48:55 UTC (rev 3344)
+++ branches/devel-threads/THREADS	2010-03-10 13:19:07 UTC (rev 3345)
@@ -33,14 +33,14 @@
     	      all headers for each child
     - button in #listcontrols to mark all messages in current thread (with selected
       root or child message),
-    - thread tree icons
-    - thread css: message row height, thread/status icon alignment
+    + thread tree icons
+    + thread css: message row height, thread/status icon alignment
       (change size of all list icons to 14x14)
     - remove 'indexsort' label from localization files
 
 TODO (by the way):
     - use jQuery.inArray instead of find_in_array() (common.js)
-    - use only one function (js) to generate messages list
+    + use only one function (js) to generate messages list
 
 KNOWN ISSUES:
     - on new message (check_recent) the whole list is reloaded

Modified: branches/devel-threads/program/js/app.js
===================================================================
--- branches/devel-threads/program/js/app.js	2010-03-09 17:48:55 UTC (rev 3344)
+++ branches/devel-threads/program/js/app.js	2010-03-10 13:19:07 UTC (rev 3345)
@@ -160,6 +160,9 @@
     switch (this.task)
       {
       case 'mail':
+        // enable mail commands
+        this.enable_command('list', 'checkmail', 'compose', 'add-contact', 'search', 'reset-search', 'collapse-folder', true);
+      
         if (this.gui_objects.messagelist)
           {
           this.message_list = new rcube_list_widget(this.gui_objects.messagelist,
@@ -181,13 +184,12 @@
             this.gui_objects.mailcontframe.onmousedown = function(e){ return p.click_on_list(e); };
           else
             this.message_list.focus();
-
-	  this.expand_threads();
+          
+          // load messages
+          if (this.env.messagecount)
+            this.command('list');
           }
 
-        // enable mail commands
-        this.enable_command('list', 'checkmail', 'compose', 'add-contact', 'search', 'reset-search', 'collapse-folder', true);
-
         if (this.env.search_text != null && document.getElementById('quicksearchbox') != null)
           document.getElementById('quicksearchbox').value = this.env.search_text;
         
@@ -1446,6 +1448,7 @@
 
   this.init_message_row = function(row)
   {
+    var self = this;
     var uid = row.uid;
     if (uid && this.env.messages[uid])
       {
@@ -1462,31 +1465,23 @@
       }
 
     // set eventhandler to message icon
-    if (this.env.subject_col != null
-	&& (row.icon = row.obj.getElementsByTagName('td')[this.env.subject_col].getElementsByTagName('img')[0]))
+    if (this.env.subject_col != null && (row.icon = document.getElementById('msgicn'+row.uid)))
       {
-      var p = this;
-      row.icon.id = 'msgicn_'+row.uid;
       row.icon._row = row.obj;
-      row.icon.onmousedown = function(e) { p.command('toggle_status', this); };
+      row.icon.onmousedown = function(e) { self.command('toggle_status', this); };
       }
 
     // set eventhandler to flag icon, if icon found
-    if (this.env.flagged_col != null
-	 && (row.flagged_icon = row.obj.getElementsByTagName('td')[this.env.flagged_col].getElementsByTagName('img')[0]))
+    if (this.env.flagged_col != null && (row.flagged_icon = document.getElementById('flaggedicn'+row.uid)))
       {
-      var p = this;
-      row.flagged_icon.id = 'flaggedicn_'+row.uid;
       row.flagged_icon._row = row.obj;
-      row.flagged_icon.onmousedown = function(e) { p.command('toggle_flag', this); };
+      row.flagged_icon.onmousedown = function(e) { self.command('toggle_flag', this); };
       }
 
     var expando;
-    if (!row.depth && row.has_children && this.env.subject_col != null
-	&& (expando = row.obj.getElementsByTagName('td')[this.env.subject_col].getElementsByTagName('div')[0]))
+    if (!row.depth && row.has_children && (expando = document.getElementById('rcmexpando'+row.uid)))
       {
-      var p = this;
-      expando.onmousedown = function(e) { return p.expand_message_row(e, uid); };
+      expando.onmousedown = function(e) { return self.expand_message_row(e, uid); };
       }
       
     this.triggerEvent('insertrow', { uid:uid, row:row });
@@ -1548,7 +1543,8 @@
       icon = this.env.forwardedicon;
     else if(flags.unread && this.env.unreadicon)
       icon = this.env.unreadicon;
-    var tree = '';
+ 
+    var tree = expando = '';
 
     if (this.env.threading)
       {
@@ -1571,13 +1567,18 @@
 
       if (width)
         tree += '<div id="rcmtab' + uid + '" class="branch" style="width:' + width + 'px;">&nbsp</div>';
+
       if (message.has_children && !message.depth)
-        tree += '<div id="rcmexpando' + uid + '" class="' + (message.expanded ? 'expanded' : 'collapsed') + '"> </div>';
-      else
-        tree += '<div class="leaf"> </div>';
+        expando = '<div id="rcmexpando' + uid + '" class="' + (message.expanded ? 'expanded' : 'collapsed') + '"> </div>';
       }
 
-    tree += icon ? '<img src="'+icon+'" alt="" />' : '';
+    tree += icon ? '<img id="msgicn'+uid+'" src="'+icon+'" alt="" class="msgicon" />' : '';
+    
+    // first col is always there
+    var col = document.createElement('td');
+    col.className = 'threads';
+    col.innerHTML = expando;
+    row.appendChild(col);
 
     // add each submitted col
     for (var n = 0; n < this.env.coltypes.length; n++) {
@@ -1588,9 +1589,9 @@
       var html;
       if (c=='flag') {
         if (flags.flagged && this.env.flaggedicon)
-          html = '<img src="'+this.env.flaggedicon+'" alt="" />';
+          html = '<img id="flaggedicn'+uid+'" src="'+this.env.flaggedicon+'" alt="" />';
         else if(!flags.flagged && this.env.unflaggedicon)
-          html = '<img src="'+this.env.unflaggedicon+'" alt="" />';
+          html = '<img id="flaggedicn'+uid+'" src="'+this.env.unflaggedicon+'" alt="" />';
         }
       else if (c=='attachment')
         html = flags.attachment && this.env.attachmenticon ? '<img src="'+this.env.attachmenticon+'" alt="" />' : ' ';
@@ -4199,7 +4200,7 @@
     for (n=0; thead && n<this.env.coltypes.length; n++)
       {
       col = this.env.coltypes[n];
-      if ((cell = thead.rows[0].cells[n]) && (col=='from' || col=='to'))
+      if ((cell = thead.rows[0].cells[n+1]) && (col=='from' || col=='to'))
         {
         // if we have links for sorting, it's a bit more complicated...
         if (cell.firstChild && cell.firstChild.tagName.toLowerCase()=='a')
@@ -4216,7 +4217,7 @@
       }
 
     // remove excessive columns
-    for (var i=n; thead && n<thead.rows[0].cells.length; i++)
+    for (var i=n+1; thead && i<thead.rows[0].cells.length; i++)
       thead.rows[0].removeChild(thead.rows[0].cells[i]);
 
     this.env.subject_col = null;

Modified: branches/devel-threads/program/localization/en_US/labels.inc
===================================================================
--- branches/devel-threads/program/localization/en_US/labels.inc	2010-03-09 17:48:55 UTC (rev 3344)
+++ branches/devel-threads/program/localization/en_US/labels.inc	2010-03-10 13:19:07 UTC (rev 3345)
@@ -172,10 +172,9 @@
 $labels['arrival'] = 'Arrival date';
 $labels['asc'] = 'ascending';
 $labels['desc'] = 'descending';
-$labels['listcolumns'] = 'List columns:';
-$labels['listsorting'] = 'Sorting column:';
-$labels['listorder'] = 'Sorting order:';
-$labels['listmode'] = 'List view mode:';
+$labels['listcolumns'] = 'List columns';
+$labels['listsorting'] = 'Sorting column';
+$labels['listmode'] = 'List view mode';
 
 $labels['compact'] = 'Compact';
 $labels['empty'] = 'Empty';

Modified: branches/devel-threads/program/steps/mail/func.inc
===================================================================
--- branches/devel-threads/program/steps/mail/func.inc	2010-03-09 17:48:55 UTC (rev 3344)
+++ branches/devel-threads/program/steps/mail/func.inc	2010-03-10 13:19:07 UTC (rev 3345)
@@ -132,27 +132,16 @@
  * return the message list as HTML table
  */
 function rcmail_message_list($attrib)
-  {
-  global $IMAP, $CONFIG, $COMM_PATH, $OUTPUT;
+{
+  global $IMAP, $CONFIG, $OUTPUT;
 
-  $skin_path = $CONFIG['skin_path'];
-  $image_tag = '<img src="%s%s" alt="%s" />';
-  
   // add some labels to client
   $OUTPUT->add_label('from', 'to');
 
-  // get message headers
-  $a_headers = $IMAP->list_headers('', '', $_SESSION['sort_col'], $_SESSION['sort_order']);
-
   // add id to message list table if not specified
   if (!strlen($attrib['id']))
     $attrib['id'] = 'rcubemessagelist';
 
-  // allow the following attributes to be added to the <table> tag
-  $attrib_str = create_attrib_string($attrib, array('style', 'class', 'id', 'cellpadding', 'cellspacing', 'border', 'summary'));
-
-  $out = '<table' . $attrib_str . ">\n";
-
   // define list of cols to be displayed based on parameter or config
   if (empty($attrib['columns']))
       $a_show_cols = is_array($CONFIG['list_cols']) ? $CONFIG['list_cols'] : array('subject');
@@ -162,7 +151,6 @@
   // save some variables for use in ajax list
   $_SESSION['list_columns'] = $a_show_cols;
   $_SESSION['list_attrib'] = $attrib;
-  $_SESSION['skin_path'] = $skin_path;
   
   $mbox = $IMAP->get_mailbox_name();
   $delim = $IMAP->get_hierarchy_delimiter();
@@ -172,139 +160,10 @@
       && ($f = array_search('from', $a_show_cols)) && !array_search('to', $a_show_cols))
     $a_show_cols[$f] = 'to';
 
-  $out .= '<thead>'.rcmail_message_list_head($attrib, $a_show_cols).'</thead>';
-  $out .= "\n<tbody>\n";
+  $out .= html::tag('thead', null, rcmail_message_list_head($attrib, $a_show_cols));
+  $out .= html::tag('tbody', null);
 
-  // no messages in this mailbox
-  if (!sizeof($a_headers))
-    $OUTPUT->show_message('nomessagesfound', 'notice');
-
-  $a_js_message_arr = array();
-
-  // create row for each message
-  foreach ($a_headers as $i => $header)  //while (list($i, $header) = each($a_headers))
-    {
-    $message_icon = $attach_icon = $flagged_icon = '';
-    $js_row_arr = array();
-    $zebra_class = $i%2 ? ' even' : ' odd';
-
-    // set messag attributes to javascript array
-    if ($header->deleted)
-      $js_row_arr['deleted'] = true;
-    if (!$header->seen)
-      $js_row_arr['unread'] = true;
-    if ($header->answered)
-      $js_row_arr['replied'] = true;
-    if ($header->forwarded)
-      $js_row_arr['forwarded'] = true;
-    if ($header->flagged)
-      $js_row_arr['flagged'] = true;
-    if ($header->has_children)
-      $js_row_arr['has_children'] = true;
-    if ($header->depth)
-      $js_row_arr['depth'] = $header->depth;
-    if ($header->parent_uid)
-      $js_row_arr['parent_uid'] = $header->parent_uid;
-    if ($header->unread_children)
-      $js_row_arr['unread_children'] = $header->unread_children;
-
-    // set message icon
-    if ($header->seen && $attrib['unreadchildrenicon'] && $header->unread_children > 0) 
-      $message_icon = $attrib['unreadchildrenicon'];
-    else if ($attrib['deletedicon'] && $header->deleted)
-      $message_icon = $attrib['deletedicon'];
-    else if ($attrib['repliedicon'] && $header->answered)
-      {
-      if ($attrib['forwardedrepliedicon'] && $header->forwarded)
-        $message_icon = $attrib['forwardedrepliedicon'];
-      else
-        $message_icon = $attrib['repliedicon'];
-      }
-    else if ($attrib['forwardedicon'] && $header->forwarded)
-      $message_icon = $attrib['forwardedicon'];
-    else if ($attrib['unreadicon'] && !$header->seen)
-      $message_icon = $attrib['unreadicon'];
-    else if ($attrib['messageicon'])
-      $message_icon = $attrib['messageicon'];
-
-    if ($attrib['flaggedicon'] && $header->flagged)
-      $flagged_icon = $attrib['flaggedicon'];
-    else if ($attrib['unflaggedicon'] && !$header->flagged)
-      $flagged_icon = $attrib['unflaggedicon'];
-    
-    // set attachment icon
-    if ($attrib['attachmenticon'] && preg_match("/multipart\/m/i", $header->ctype))
-      $attach_icon = $attrib['attachmenticon'];
-        
-    $out .= sprintf('<tr id="rcmrow%d" class="message%s%s%s%s%s"%s>'."\n",
-                    $header->uid,
-                    $header->seen ? '' : ' unread',
-                    $header->deleted ? ' deleted' : '',
-                    $header->flagged ? ' flagged' : '',
-                    $header->unread_children && $header->seen ? ' unroot' : '',
-                    $zebra_class,
-