From da8f11ce163ffe3f88a359ae613aa144b16c73fc Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Thu, 15 Apr 2010 07:28:15 -0400
Subject: [PATCH] - Fix messages list scrolling in FF3.6 (#1486472) - Fix quicksearch input focus (#1486637) - Small code cleanup + improvements

---
 program/js/list.js          |    4 
 CHANGELOG                   |    2 
 program/steps/mail/func.inc |    1 
 program/js/app.js           |  348 ++++++++++++++++++++++++++-------------------------------
 4 files changed, 165 insertions(+), 190 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 6612dab..0f3c1d0 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,8 @@
 CHANGELOG RoundCube Webmail
 ===========================
 
+- Fix messages list scrolling in FF3.6 (#1486472)
+- Fix quicksearch input focus (#1486637)
 - Always set changed date when flagging a DB record as deleted + provide a cleanup script
 - Fix address book/group selection (#1486619)
 - Assign newly created contacts to the active group (#1486626)
diff --git a/program/js/app.js b/program/js/app.js
index 57a1a8e..9c5df76 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -55,7 +55,8 @@
   this.env.blankpage = 'program/blank.gif';
 
   // set jQuery ajax options
-  jQuery.ajaxSetup({ cache:false,
+  jQuery.ajaxSetup({
+    cache:false,
     error:function(request, status, err){ ref.http_error(request, status, err); },
     beforeSend:function(xmlhttp){ xmlhttp.setRequestHeader('X-RoundCube-Request', ref.env.request_token); }
   });
@@ -131,8 +132,7 @@
     this.task = this.env.task;
     
     // check browser
-    if (!bw.dom || !bw.xmlhttp_test())
-      {
+    if (!bw.dom || !bw.xmlhttp_test()) {
       this.goto_url('error', '_code=0x199');
       return;
       }
@@ -176,69 +176,64 @@
           this.message_list.addEventListener('dragmove', function(e){ p.drag_move(e); });
           this.message_list.addEventListener('dragend', function(e){ p.drag_end(e); });
           this.message_list.addEventListener('expandcollapse', function(e){ p.msglist_expand(e); });
+
           document.onmouseup = function(e){ return p.doc_mouse_up(e); };
+          this.gui_objects.messagelist.parentNode.onmousedown = function(e){ return p.click_on_list(e); };
 
           this.set_message_coltypes(this.env.coltypes);
           this.message_list.init();
           this.enable_command('toggle_status', 'toggle_flag', 'menu-open', 'menu-save', true);
-          
-          if (this.gui_objects.mailcontframe)
-            this.gui_objects.mailcontframe.onmousedown = function(e){ return p.click_on_list(e); };
-          else
-            this.message_list.focus();
           
           // load messages
           if (this.env.messagecount)
             this.command('list');
           }
 
-        if (this.env.search_text != null && document.getElementById('quicksearchbox') != null)
-          document.getElementById('quicksearchbox').value = this.env.search_text;
-        
-        if (this.env.action=='show' || this.env.action=='preview')
-          {
-          this.enable_command('show', 'reply', 'reply-all', 'forward', 'moveto', 'copy', 'delete',
-            'open', 'mark', 'edit', 'viewsource', 'download', 'print', 'load-attachment', 'load-headers', true);
-
-          if (this.env.next_uid)
-            {
-            this.enable_command('nextmessage', true);
-            this.enable_command('lastmessage', true);
+        if (this.gui_objects.qsearchbox) {
+          if (this.env.search_text != null) {
+            this.gui_objects.qsearchbox.value = this.env.search_text;
             }
-          if (this.env.prev_uid)
-            {
-            this.enable_command('previousmessage', true);
-            this.enable_command('firstmessage', true);
-            }
-        
-          if (this.env.blockedobjects)
-            {
-            if (this.gui_objects.remoteobjectsmsg)
-              this.gui_objects.remoteobjectsmsg.style.display = 'block';
-            this.enable_command('load-images', 'always-load', true);
-            }
+          $(this.gui_objects.qsearchbox).focusin(function() { rcmail.message_list.blur(); });
           }
 
         if (this.env.trash_mailbox && this.env.mailbox != this.env.trash_mailbox)
           this.set_alttext('delete', 'movemessagetotrash');
-        
-        // make preview/message frame visible
-        if (this.env.action == 'preview' && this.env.framed && parent.rcmail)
-          {
-          this.enable_command('compose', 'add-contact', false);
-          parent.rcmail.show_contentframe(true);
-          }
 
-        if (this.env.action=='compose')
-          {
+        if (this.env.action=='show' || this.env.action=='preview') {
+          this.enable_command('show', 'reply', 'reply-all', 'forward', 'moveto', 'copy', 'delete',
+            'open', 'mark', 'edit', 'viewsource', 'download', 'print', 'load-attachment', 'load-headers', true);
+
+          if (this.env.next_uid) {
+            this.enable_command('nextmessage', true);
+            this.enable_command('lastmessage', true);
+            }
+          if (this.env.prev_uid) {
+            this.enable_command('previousmessage', true);
+            this.enable_command('firstmessage', true);
+            }
+        
+          if (this.env.blockedobjects) {
+            if (this.gui_objects.remoteobjectsmsg)
+              this.gui_objects.remoteobjectsmsg.style.display = 'block';
+            this.enable_command('load-images', 'always-load', true);
+            }
+
+          // make preview/message frame visible
+          if (this.env.action == 'preview' && this.env.framed && parent.rcmail) {
+            this.enable_command('compose', 'add-contact', false);
+            parent.rcmail.show_contentframe(true);
+            }
+          }
+        else if (this.env.action == 'compose') {
           this.enable_command('add-attachment', 'send-attachment', 'remove-attachment', 'send', true);
-          if (this.env.spellcheck)
-            {
+
+          if (this.env.spellcheck) {
             this.env.spellcheck.spelling_state_observer = function(s){ ref.set_spellcheck_state(s); };
             this.set_spellcheck_state('ready');
             if ($("input[name='_is_html']").val() == '1')
               this.display_spellcheck_controls(false);
             }
+
           if (this.env.drafts_mailbox)
             this.enable_command('savedraft', true);
             
@@ -247,38 +242,35 @@
           // init message compose form
           this.init_messageform();
           }
+        // show printing dialog
+        else if (this.env.action == 'print')
+          window.print();
 
         if (this.env.messagecount) {
           this.enable_command('select-all', 'select-none', 'expunge', true);
           this.enable_command('expand-all', 'expand-unread', 'collapse-all', this.env.threading);
-        }
+          }
 
         if (this.purge_mailbox_test())
           this.enable_command('purge', true);
 
         this.set_page_buttons();
 
-        // show printing dialog
-        if (this.env.action=='print')
-          window.print();
-
         // get unread count for each mailbox
-        if (this.gui_objects.mailboxlist)
-        {
+        if (this.gui_objects.mailboxlist) {
           this.env.unread_counts = {};
           this.gui_objects.folderlist = this.gui_objects.mailboxlist;
           this.http_request('getunread', '');
-        }
+          }
         
         // ask user to send MDN
-        if (this.env.mdn_request && this.env.uid)
-        {
+        if (this.env.mdn_request && this.env.uid) {
           var mdnurl = '_uid='+this.env.uid+'&_mbox='+urlencode(this.env.mailbox);
           if (confirm(this.get_label('mdnrequest')))
             this.http_post('sendmdn', mdnurl);
           else
             this.http_post('mark', mdnurl+'&_flag=mdnsent');
-        }
+          }
 
         break;
 
@@ -302,15 +294,11 @@
           if (this.env.cid)
             this.contact_list.highlight_row(this.env.cid);
 
-          if (this.gui_objects.contactslist.parentNode)
-            {
-            this.gui_objects.contactslist.parentNode.onmousedown = function(e){ return p.click_on_list(e); };
-            document.onmouseup = function(e){ return p.doc_mouse_up(e); };
+          this.gui_objects.contactslist.parentNode.onmousedown = function(e){ return p.click_on_list(e); };
+          document.onmouseup = function(e){ return p.doc_mouse_up(e); };
+          if (this.gui_objects.qsearchbox) {
+            $(this.gui_objects.qsearchbox).focusin(function() { rcmail.contact_list.blur(); });
             }
-          else
-            this.contact_list.focus();
-            
-          //this.gui_objects.folderlist = this.gui_objects.contactslist;
           }
 
         this.set_page_buttons();
@@ -405,8 +393,7 @@
     
     // execute all foreign onload scripts
     // @deprecated
-    for (var i=0; i<this.onloads.length; i++)
-      {
+    for (var i=0; i<this.onloads.length; i++) {
       if (typeof(this.onloads[i]) == 'string')
         eval(this.onloads[i]);
       else if (typeof(this.onloads[i]) == 'function')
@@ -500,8 +487,7 @@
 
       case 'open':
         var uid;
-        if (uid = this.get_single_uid())
-        {
+        if (uid = this.get_single_uid()) {
           obj.href = '?_task='+this.env.task+'&_action=show&_mbox='+urlencode(this.env.mailbox)+'&_uid='+uid;
           return true;
         }
@@ -509,8 +495,7 @@
 
       // misc list commands
       case 'list':
-        if (this.task=='mail')
-          {
+        if (this.task=='mail') {
           if (this.env.search_request<0 || (props != '' && (this.env.search_request && props != this.env.mailbox)))
             this.reset_qsearch();
 
@@ -518,15 +503,14 @@
 
           if (this.env.trash_mailbox)
             this.set_alttext('delete', this.env.mailbox != this.env.trash_mailbox ? 'movemessagetotrash' : 'deletemessage');
-          }
-        else if (this.task=='addressbook')
-          {
+        }
+        else if (this.task=='addressbook') {
           if (this.env.search_request<0 || (this.env.search_request && props != this.env.source))
             this.reset_qsearch();
 
           this.list_contacts(props);
           this.enable_command('add', 'import', (this.env.address_sources && !this.env.address_sources[this.env.source].readonly));
-          }
+        }
         break;
 
 
@@ -585,33 +569,29 @@
 
       // common commands used in multiple tasks
       case 'show':
-        if (this.task=='mail')
-          {
+        if (this.task=='mail') {
           var uid = this.get_single_uid();
-          if (uid && (!this.env.uid || uid != this.env.uid))
-            {
+          if (uid && (!this.env.uid || uid != this.env.uid)) {
             if (this.env.mailbox == this.env.drafts_mailbox)
               this.goto_url('compose', '_draft_uid='+uid+'&_mbox='+urlencode(this.env.mailbox), true);
             else
               this.show_message(uid);
-            }
           }
-        else if (this.task=='addressbook')
-          {
+        }
+        else if (this.task=='addressbook') {
           var cid = props ? props : this.get_single_cid();
           if (cid && !(this.env.action=='show' && cid==this.env.cid))
             this.load_contact(cid, 'show');
-          }
+        }
         break;
 
       case 'add':
         if (this.task=='addressbook')
           this.load_contact(0, 'add');
-        else if (this.task=='settings')
-          {
+        else if (this.task=='settings') {
           this.identity_list.clear_selection();
           this.load_identity(0, 'add-identity');
-          }
+        }
         break;
 
       case 'edit':
@@ -700,16 +680,16 @@
         var uid;
         var flag = 'read';
         
-        if (props._row.uid)
-          {
+        if (props._row.uid) {
           uid = props._row.uid;
           
           // toggle read/unread
           if (this.message_list.rows[uid].deleted) {
             flag = 'undelete';
-          } else if (!this.message_list.rows[uid].unread)
-            flag = 'unread';
           }
+          else if (!this.message_list.rows[uid].unread)
+            flag = 'unread';
+        }
           
         this.mark_message(flag, uid);
         break;
@@ -721,8 +701,7 @@
         var uid;
         var flag = 'flagged';
 
-        if (props._row.uid)
-          {
+        if (props._row.uid) {
           uid = props._row.uid;
           // toggle flagged/unflagged
           if (this.message_list.rows[uid].flagged)
@@ -747,17 +726,15 @@
         var qstring = '_mbox='+urlencode(this.env.mailbox)+'&_uid='+this.env.uid+'&_part='+props.part;
         
         // open attachment in frame if it's of a supported mimetype
-        if (this.env.uid && props.mimetype && jQuery.inArray(props.mimetype, this.mimetypes)>=0)
-          {
+        if (this.env.uid && props.mimetype && jQuery.inArray(props.mimetype, this.mimetypes)>=0) {
           if (props.mimetype == 'text/html')
             qstring += '&_safe=1';
           this.attachment_win = window.open(this.env.comm_path+'&_action=get&'+qstring+'&_frame=1', 'rcubemailattachment');
-          if (this.attachment_win)
-            {
+          if (this.attachment_win) {
             window.setTimeout(function(){ ref.attachment_win.focus(); }, 10);
             break;
-            }
           }
+        }
 
         this.goto_url('get', qstring+'&_download=1', false);
         break;
@@ -817,12 +794,10 @@
       case 'compose':
         var url = this.env.comm_path+'&_action=compose';
        
-        if (this.task=='mail')
-        {
+        if (this.task=='mail') {
           url += '&_mbox='+urlencode(this.env.mailbox);
           
-          if (this.env.mailbox==this.env.drafts_mailbox)
-          {
+          if (this.env.mailbox==this.env.drafts_mailbox) {
             var uid;
             if (uid = this.get_single_uid())
               url += '&_draft_uid='+uid;
@@ -831,36 +806,33 @@
              url += '&_to='+urlencode(props);
         }
         // modify url if we're in addressbook
-        else if (this.task=='addressbook')
-          {
+        else if (this.task=='addressbook') {
           // switch to mail compose step directly
-          if (props && props.indexOf('@') > 0)
-            {
+          if (props && props.indexOf('@') > 0) {
             url = this.get_task_url('mail', url);
             this.redirect(url + '&_to='+urlencode(props));
             break;
-            }
+          }
           
           // use contact_id passed as command parameter
           var a_cids = new Array();
           if (props)
             a_cids[a_cids.length] = props;
           // get selected contacts
-          else if (this.contact_list)
-            {
+          else if (this.contact_list) {
             var selection = this.contact_list.get_selection();
             for (var n=0; n<selection.length; n++)
               a_cids[a_cids.length] = selection[n];
-            }
+          }
             
           if (a_cids.length)
             this.http_request('mailto', '_cid='+urlencode(a_cids.join(','))+'&_source='+urlencode(this.env.source), true);
 
           break;
-          }
+        }
 
         // don't know if this is necessary...
-        url = url.replace(/&_framed=1/, "");
+        url = url.replace(/&_framed=1/, '');
 
         this.redirect(url);
         break;
@@ -1199,47 +1171,6 @@
   /*********        event handling methods         *********/
   /*********************************************************/
 
-  this.doc_mouse_up = function(e)
-  {
-    var model, list, li;
-
-    if (this.message_list) {
-      if (!rcube_mouse_is_over(e, this.message_list.list))
-        this.message_list.blur();
-      list = this.message_list;
-      model = this.env.mailboxes;
-    }
-    else if (this.contact_list) {
-      if (!rcube_mouse_is_over(e, this.contact_list.list))
-        this.contact_list.blur();
-      list = this.contact_list;
-      model = this.env.contactfolders;
-    }
-    else if (this.ksearch_value) {
-      this.ksearch_blur();
-    }
-
-    // handle mouse release when dragging
-    if (this.drag_active && model && this.env.last_folder_target) {
-      var target = model[this.env.last_folder_target];
-      
-      $(this.get_folder_li(this.env.last_folder_target)).removeClass('droptarget');
-      this.env.last_folder_target = null;
-      list.draglayer.hide();
-
-      if (!this.drag_menu(e, target))
-        this.command('moveto', target);
-    }
-    
-    // reset 'pressed' buttons
-    if (this.buttons_sel) {
-      for (var id in this.buttons_sel)
-        if (typeof id != 'function')
-          this.button_out(this.buttons_sel[id], id);
-      this.buttons_sel = {};
-    }
-  };
-
   this.drag_menu = function(e, target)
   {
     var modkey = rcube_event.get_modifier(e);
@@ -1351,7 +1282,7 @@
             && this.check_droptarget(k)) {
 
           li = this.get_folder_li(k);
-          div = $(li.getElementsByTagName("div")[0]);
+          div = $(li.getElementsByTagName('div')[0]);
 
           // if the folder is collapsed, expand it after 1sec and restart the drag & drop process.
           if (div.hasClass('collapsed')) {
@@ -1360,7 +1291,7 @@
             
             this.folder_auto_expand = k;
             this.folder_auto_timer = window.setTimeout(function() {
-                rcmail.command("collapse-folder", rcmail.folder_auto_expand);
+                rcmail.command('collapse-folder', rcmail.folder_auto_expand);
                 rcmail.drag_start(null);
               }, 1000);
           } else if (this.folder_auto_timer) {
@@ -1382,46 +1313,87 @@
   };
 
   this.collapse_folder = function(id)
-    {
-    var div;
-    if ((li = this.get_folder_li(id)) &&
-        (div = $(li.getElementsByTagName("div")[0])) &&
-        (div.hasClass('collapsed') || div.hasClass('expanded')))
-      {
-      var ul = $(li.getElementsByTagName("ul")[0]);
-      if (div.hasClass('collapsed'))
-        {
-        ul.show();
-        div.removeClass('collapsed').addClass('expanded');
-        var reg = new RegExp('&'+urlencode(id)+'&');
-        this.set_env('collapsed_folders', this.env.collapsed_folders.replace(reg, ''));
-        }
-      else
-        {
-        ul.hide();
-        div.removeClass('expanded').addClass('collapsed');
-        this.set_env('collapsed_folders', this.env.collapsed_folders+'&'+urlencode(id)+'&');
+  {
+    var li = this.get_folder_li(id);
+    var div = $(li.getElementsByTagName('div')[0]);
+    
+    if (!div || (!div.hasClass('collapsed') && !div.hasClass('expanded')))
+      return;
+    
+    var ul = $(li.getElementsByTagName('ul')[0]);
+    if (div.hasClass('collapsed')) {
+      ul.show();
+      div.removeClass('collapsed').addClass('expanded');
+      var reg = new RegExp('&'+urlencode(id)+'&');
+      this.set_env('collapsed_folders', this.env.collapsed_folders.replace(reg, ''));
+    }
+    else {
+      ul.hide();
+      div.removeClass('expanded').addClass('collapsed');
+      this.set_env('collapsed_folders', this.env.collapsed_folders+'&'+urlencode(id)+'&');
 
-        // select parent folder if one of its childs is currently selected
-        if (this.env.mailbox.indexOf(id + this.env.delimiter) == 0)
-          this.command('list', id);
-        }
+      // select parent folder if one of its childs is currently selected
+      if (this.env.mailbox.indexOf(id + this.env.delimiter) == 0)
+        this.command('list', id);
+    }
 
-      // Work around a bug in IE6 and IE7, see #1485309
-      if ((bw.ie6 || bw.ie7) &&
-          li.nextSibling &&
-          (li.nextSibling.getElementsByTagName("ul").length>0) &&
-          li.nextSibling.getElementsByTagName("ul")[0].style &&
-          (li.nextSibling.getElementsByTagName("ul")[0].style.display!='none'))
-        {
-          li.nextSibling.getElementsByTagName("ul")[0].style.display = 'none';
-          li.nextSibling.getElementsByTagName("ul")[0].style.display = '';
-        }
-
-      this.http_post('save-pref', '_name=collapsed_folders&_value='+urlencode(this.env.collapsed_folders));
-      this.set_unread_count_display(id, false);
+    // Work around a bug in IE6 and IE7, see #1485309
+    if (bw.ie6 || bw.ie7) {
+      var siblings = li.nextSibling ? li.nextSibling.getElementsByTagName('ul') : null;
+      if (siblings && siblings.length && (li = siblings[0]) && li.style && li.style.display != 'none') {
+        li.style.display = 'none';
+        li.style.display = '';
       }
     }
+
+    this.http_post('save-pref', '_name=collapsed_folders&_value='+urlencode(this.env.collapsed_folders));
+    this.set_unread_count_display(id, false);
+  };
+
+  this.doc_mouse_up = function(e)
+  {
+    var model, list, li;
+
+    if (this.message_list) {
+      if (!rcube_mouse_is_over(e, this.message_list.list.parentNode))
+        this.message_list.blur();
+      else
+        this.message_list.focus();
+      list = this.message_list;
+      model = this.env.mailboxes;
+    }
+    else if (this.contact_list) {
+      if (!rcube_mouse_is_over(e, this.contact_list.list.parentNode))
+        this.contact_list.blur();
+      else
+        this.contact_list.focus();
+      list = this.contact_list;
+      model = this.env.contactfolders;
+    }
+    else if (this.ksearch_value) {
+      this.ksearch_blur();
+    }
+
+    // handle mouse release when dragging
+    if (this.drag_active && model && this.env.last_folder_target) {
+      var target = model[this.env.last_folder_target];
+      
+      $(this.get_folder_li(this.env.last_folder_target)).removeClass('droptarget');
+      this.env.last_folder_target = null;
+      list.draglayer.hide();
+
+      if (!this.drag_menu(e, target))
+        this.command('moveto', target);
+    }
+
+    // reset 'pressed' buttons
+    if (this.buttons_sel) {
+      for (var id in this.buttons_sel)
+        if (typeof id != 'function')
+          this.button_out(this.buttons_sel[id], id);
+      this.buttons_sel = {};
+    }
+  };
 
   this.click_on_list = function(e)
     {
@@ -1433,7 +1405,7 @@
     else if (this.contact_list)
       this.contact_list.focus();
 
-    return rcube_event.get_button(e) == 2 ? true : rcube_event.cancel(e);
+    return true;
     };
 
   this.msglist_select = function(list)
diff --git a/program/js/list.js b/program/js/list.js
index ad640fb..3e7bc62 100644
--- a/program/js/list.js
+++ b/program/js/list.js
@@ -1159,6 +1159,8 @@
       this.draglayer.hide();
   }
 
+  if (this.drag_active)
+    this.focus();
   this.drag_active = false;
 
   rcube_event.remove_listener({event:'mousemove', object:this, method:'drag_mouse_move'});
@@ -1168,7 +1170,7 @@
   $('div.iframe-dragdrop-fix').each(function() { this.parentNode.removeChild(this); });
 
   this.triggerEvent('dragend');
-    
+
   return rcube_event.cancel(e);
 },
 
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index 1cac615..ad4ca22 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -175,7 +175,6 @@
   $message_count = $IMAP->messagecount(NULL, $IMAP->threading ? 'THREADS' : 'ALL');
   
   // set client env
-  $OUTPUT->add_gui_object('mailcontframe', 'mailcontframe');
   $OUTPUT->add_gui_object('messagelist', $attrib['id']);
   $OUTPUT->set_env('autoexpand_threads', intval($CONFIG['autoexpand_threads']));
   $OUTPUT->set_env('messagecount', $message_count);

--
Gitblit v1.9.1