From 4764079c6af092a6dfa18306601e1b33482fb756 Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Thu, 05 May 2011 03:26:50 -0400
Subject: [PATCH] - Fix bug where messages were deleted instead moved to trash folder after Shift key was used (#1487902), small code improvements

---
 program/js/app.js |  251 ++++++++++++++++++++++++-------------------------
 1 files changed, 124 insertions(+), 127 deletions(-)

diff --git a/program/js/app.js b/program/js/app.js
index f81f8d5..99446d6 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -136,8 +136,8 @@
     }
 
     // Enable debug console
-    if (!window.console) {
-      console = new rcube_console();
+    if (!window.console || !window.console.log) {
+      window.console = new rcube_console();
     }
     else {
       $('#console').hide();
@@ -324,22 +324,9 @@
           }
         }
 
-        if ((this.env.action=='add' || this.env.action=='edit') && this.gui_objects.editform) {
+        if ((this.env.action == 'add' || this.env.action == 'edit') && this.gui_objects.editform) {
           this.enable_command('save', true);
-          this.enable_command('upload-photo', this.env.coltypes.photo ? true : false);
-          this.enable_command('delete-photo', this.env.coltypes.photo && this.env.action == 'edit');
-
-          for (var col in this.env.coltypes)
-            this.init_edit_field(col, null);
-
-          $('.contactfieldgroup .row a.deletebutton').click(function(){ ref.delete_edit_field(this); return false });
-
-          $('select.addfieldmenu').change(function(e){
-            ref.insert_edit_field($(this).val(), $(this).attr('rel'), this);
-            this.selectedIndex = 0;
-          });
-
-          $("input[type='text']:visible").first().focus();
+          this.init_contact_form();
         }
         else if (this.gui_objects.qsearchbox) {
           this.enable_command('search', 'reset-search', 'moveto', true);
@@ -356,14 +343,14 @@
       case 'settings':
         this.enable_command('preferences', 'identities', 'save', 'folders', true);
 
-        if (this.env.action=='identities') {
+        if (this.env.action == 'identities') {
           this.enable_command('add', this.env.identities_level < 2);
         }
-        else if (this.env.action=='edit-identity' || this.env.action=='add-identity') {
+        else if (this.env.action == 'edit-identity' || this.env.action == 'add-identity') {
           this.enable_command('add', this.env.identities_level < 2);
           this.enable_command('save', 'delete', 'edit', 'toggle-editor', true);
         }
-        else if (this.env.action=='folders') {
+        else if (this.env.action == 'folders') {
           this.enable_command('subscribe', 'unsubscribe', 'create-folder', 'rename-folder', true);
         }
         else if (this.env.action == 'edit-folder' && this.gui_objects.editform) {
@@ -486,13 +473,13 @@
 
     // trigger plugin hooks
     this.triggerEvent('actionbefore', {props:props, action:command});
-    var event_ret = this.triggerEvent('before'+command, props);
-    if (event_ret !== undefined) {
+    var ret = this.triggerEvent('before'+command, props);
+    if (ret !== undefined) {
       // abort if one the handlers returned false
-      if (event_ret === false)
+      if (ret === false)
         return false;
       else
-        props = event_ret;
+        props = ret;
     }
 
     // process internal command
@@ -654,7 +641,7 @@
               input_name.focus();
               break;
             }
-            else if (this.task == 'settings' && input_email.length && !rcube_check_email(input_email.val())) {
+            else if (this.task == 'settings' && input_email.length && (this.env.identities_level % 2) == 0 && !rcube_check_email(input_email.val())) {
               alert(this.get_label('noemailwarning'));
               input_email.focus();
               break;
@@ -670,13 +657,13 @@
 
       case 'delete':
         // mail task
-        if (this.task=='mail')
+        if (this.task == 'mail')
           this.delete_messages();
         // addressbook task
-        else if (this.task=='addressbook')
+        else if (this.task == 'addressbook')
           this.delete_contacts();
         // user settings task
-        else if (this.task=='settings')
+        else if (this.task == 'settings')
           this.delete_identity();
         break;
 
@@ -821,10 +808,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;
@@ -833,7 +820,7 @@
              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) {
             url = this.get_task_url('mail', url);
@@ -842,24 +829,21 @@
           }
 
           // use contact_id passed as command parameter
-          var a_cids = [];
+          var n, len, a_cids = [];
           if (props)
             a_cids.push(props);
           // get selected contacts
           else if (this.contact_list) {
             var selection = this.contact_list.get_selection();
-            for (var n=0; n<selection.length; n++)
+            for (n=0, len=selection.length; n<len; n++)
               a_cids.push(selection[n]);
           }
 
           if (a_cids.length)
-            this.http_request('mailto', '_cid='+urlencode(a_cids.join(','))+'&_source='+urlencode(this.env.source), true);
+            this.http_post('mailto', {_cid: a_cids.join(','), _source: this.env.source}, true);
 
           break;
         }
-
-        // don't know if this is necessary...
-        url = url.replace(/&_framed=1/, '');
 
         this.redirect(url);
         break;
@@ -1380,22 +1364,20 @@
 
   this.doc_mouse_up = function(e)
   {
-    var model, list, li;
+    var model, list, li, id;
 
-    if (this.message_list) {
-      if (!rcube_mouse_is_over(e, this.message_list.list.parentNode))
-        this.message_list.blur();
+    if (list = this.message_list) {
+      if (!rcube_mouse_is_over(e, list.list.parentNode))
+        list.blur();
       else
-        this.message_list.focus();
-      list = this.message_list;
+        list.focus();
       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 if (list = this.contact_list) {
+      if (!rcube_mouse_is_over(e, list.list.parentNode))
+        list.blur();
       else
-        this.contact_list.focus();
-      list = this.contact_list;
+        list.focus();
       model = this.env.contactfolders;
     }
     else if (this.ksearch_value) {
@@ -1416,7 +1398,7 @@
 
     // reset 'pressed' buttons
     if (this.buttons_sel) {
-      for (var id in this.buttons_sel)
+      for (id in this.buttons_sel)
         if (typeof id !== 'function')
           this.button_out(this.buttons_sel[id], id);
       this.buttons_sel = {};
@@ -1515,8 +1497,6 @@
       this.command('previouspage');
     else if (list.key_pressed == 34)
       this.command('nextpage');
-    else
-      list.shiftkey = false;
   };
 
   this.msglist_get_preview = function()
@@ -2442,17 +2422,19 @@
   // delete selected messages from the current mailbox
   this.delete_messages = function()
   {
-    var selection = this.message_list ? $.merge([], this.message_list.get_selection()) : [];
+    var uid, i, len, trash = this.env.trash_mailbox,
+      list = this.message_list,
+      selection = list ? $.merge([], list.get_selection()) : [];
 
     // exit if no mailbox specified or if selection is empty
     if (!this.env.uid && !selection.length)
       return;
 
     // also select childs of collapsed rows
-    for (var uid, i=0, len=selection.length; i<len; i++) {
+    for (i=0, len=selection.length; i<len; i++) {
       uid = selection[i];
-      if (this.message_list.rows[uid].has_children && !this.message_list.rows[uid].expanded)
-        this.message_list.select_childs(uid);
+      if (list.rows[uid].has_children && !list.rows[uid].expanded)
+        list.select_childs(uid);
     }
 
     // if config is set to flag for deletion
@@ -2461,17 +2443,18 @@
       return false;
     }
     // if there isn't a defined trash mailbox or we are in it
-    else if (!this.env.trash_mailbox || this.env.mailbox == this.env.trash_mailbox)
+    // @TODO: we should check if defined trash mailbox exists
+    else if (!trash || this.env.mailbox == trash)
       this.permanently_remove_messages();
     // if there is a trash mailbox defined and we're not currently in it
     else {
       // if shift was pressed delete it immediately
-      if (this.message_list && this.message_list.shiftkey) {
+      if (list && list.shiftkey) {
         if (confirm(this.get_label('deletemessagesconfirm')))
           this.permanently_remove_messages();
       }
       else
-        this.move_messages(this.env.trash_mailbox);
+        this.move_messages(trash);
     }
 
     return true;
@@ -3021,11 +3004,11 @@
   this.compose_field_hash = function(save)
   {
     // check input fields
-    var value_to = $("[name='_to']").val();
-    var value_cc = $("[name='_cc']").val();
-    var value_bcc = $("[name='_bcc']").val();
-    var value_subject = $("[name='_subject']").val();
-    var str = '';
+    var ed, str = '',
+      value_to = $("[name='_to']").val(),
+      value_cc = $("[name='_cc']").val(),
+      value_bcc = $("[name='_bcc']").val(),
+      value_subject = $("[name='_subject']").val();
 
     if (value_to)
       str += value_to+':';
@@ -3036,9 +3019,8 @@
     if (value_subject)
       str += value_subject+':';
 
-    var editor = tinyMCE.get(this.env.composebody);
-    if (editor)
-      str += editor.getContent();
+    if (window.tinyMCE && (ed = tinyMCE.get(this.env.composebody)))
+      str += ed.getContent();
     else
       str += $("[name='_message']").val();
 
@@ -3188,16 +3170,12 @@
     if (!form)
       return false;
 
-    // get file input fields
-    var send = false;
-    for (var n=0; n<form.elements.length; n++)
-      if (form.elements[n].type=='file' && form.elements[n].value) {
-        send = true;
-        break;
-      }
+    // get file input field, count files on capable browser
+    var field = $('input[type=file]', form).get(0),
+      files = field.files ? field.files.length : field.value ? 1 : 0;
 
     // create hidden iframe and post upload form
-    if (send) {
+    if (files) {
       var frame_name = this.async_upload_form(form, 'upload', function(e) {
         var d, content = '';
         try {
@@ -3220,7 +3198,7 @@
       });
 
       // display upload indicator and cancel button
-      var content = this.get_label('uploading'),
+      var content = this.get_label('uploading' + (files > 1 ? 'many' : '')),
         ts = frame_name.replace(/^rcmupload/, '');
 
       if (this.env.loadingicon)
@@ -3242,8 +3220,7 @@
     if (!this.gui_objects.attachmentlist)
       return false;
 
-    var li = $('<li>').attr('id', name).html(att.html);
-    var indicator;
+    var indicator, li = $('<li>').attr('id', name).html(att.html);
 
     // replace indicator's li
     if (upload_id && (indicator = document.getElementById(upload_id))) {
@@ -3270,7 +3247,7 @@
       return false;
 
     var list = this.gui_objects.attachmentlist.getElementsByTagName("li");
-    for (i=0;i<list.length;i++)
+    for (i=0; i<list.length; i++)
       if (list[i].id == name)
         this.gui_objects.attachmentlist.removeChild(list[i]);
   };
@@ -3599,7 +3576,7 @@
 
     if (this.ksearch_pane)
       this.ksearch_pane.hide();
-  };
+   };
 
 
   /*********************************************************/
@@ -3790,28 +3767,25 @@
   // update a contact record in the list
   this.update_contact_row = function(cid, cols_arr, newcid)
   {
-    cid = String(cid).replace(this.identifier_expr, '_');
-    newcid = String(newcid).replace(this.identifier_expr, '_');
+    var c, row, list = this.contact_list;
 
-    var row;
-    if (this.contact_list.rows[cid] && (row = this.contact_list.rows[cid].obj)) {
-      for (var c=0; c<cols_arr.length; c++)
+    cid = String(cid).replace(this.identifier_expr, '_');
+
+    if (list.rows[cid] && (row = list.rows[cid].obj)) {
+      for (c=0; c<cols_arr.length; c++)
         if (row.cells[c])
           $(row.cells[c]).html(cols_arr[c]);
 
       // cid change
       if (newcid) {
+        newcid = String(newcid).replace(this.identifier_expr, '_');
         row.id = 'rcmrow' + newcid;
-        this.contact_list.remove_row(cid);
-        this.contact_list.init_row(row);
-        this.contact_list.selection[0] = newcid;
+        list.remove_row(cid);
+        list.init_row(row);
+        list.selection[0] = newcid;
         row.style.display = '';
       }
-
-      return true;
     }
-
-    return false;
   };
 
   // add row to contacts list
@@ -3842,6 +3816,28 @@
     this.contact_list.insert_row(row);
 
     this.enable_command('export', (this.contact_list.rowcount > 0));
+  };
+
+  this.init_contact_form = function()
+  {
+    var ref = this, col;
+
+    this.set_photo_actions($('#ff_photo').val());
+
+    for (col in this.env.coltypes)
+      this.init_edit_field(col, null);
+
+    $('.contactfieldgroup .row a.deletebutton').click(function() {
+      ref.delete_edit_field(this);
+      return false;
+    });
+
+    $('select.addfieldmenu').change(function(e) {
+      ref.insert_edit_field($(this).val(), $(this).attr('rel'), this);
+      this.selectedIndex = 0;
+    });
+
+    $("input[type='text']:visible").first().focus();
   };
 
   this.group_create = function()
@@ -3984,11 +3980,11 @@
       this.env.contactfolders[newkey] = this.env.contactfolders[key];
       this.env.contactfolders[newkey].id = prop.newid;
       this.env.group = prop.newid;
-      
+
       var newprop = $.extend({}, prop);
       newprop.id = prop.newid;
       newprop.type = 'group';
-      
+
       link = $('<a>').attr('href', '#')
         .attr('rel', prop.source+':'+prop.newid)
         .bind('click', function() { return rcmail.command('listgroup', newprop, this);})
@@ -4008,7 +4004,7 @@
   {
     if (!elem)
       elem = $('.ff_' + col);
-    
+
     elem.focus(function(){ ref.focus_textfield(this); })
       .blur(function(){ ref.blur_textfield(this); })
       .each(function(){ this._placeholder = this.title = ref.env.coltypes[col].label; ref.blur_textfield(this); });
@@ -4140,26 +4136,31 @@
       this.photo_upload_id = this.set_busy(true, 'uploading');
     }
   };
-  
+
   this.replace_contact_photo = function(id)
   {
-    $('#ff_photo').val(id);
-    
-    var buttons = this.buttons['upload-photo'];
-    for (var n=0; n < buttons.length; n++)
-      $('#'+buttons[n].id).html(this.get_label(id == '-del-' ? 'addphoto' : 'replacephoto'));
-    
     var img_src = id == '-del-' ? this.env.photo_placeholder :
       this.env.comm_path + '&_action=photo&_source=' + this.env.source + '&_cid=' + this.env.cid + '&_photo=' + id;
+
+    this.set_photo_actions(id);
     $(this.gui_objects.contactphoto).children('img').attr('src', img_src);
-    
-    this.enable_command('delete-photo', id != '-del-');
   };
-  
+
   this.photo_upload_end = function()
   {
     this.set_busy(false, null, this.photo_upload_id);
     delete this.photo_upload_id;
+  };
+
+  this.set_photo_actions = function(id)
+  {
+    var n, buttons = this.buttons['upload-photo'];
+    for (n=0; n < buttons.length; n++)
+      $('#'+buttons[n].id).html(this.get_label(id == '-del-' ? 'addphoto' : 'replacephoto'));
+
+    $('#ff_photo').val(id);
+    this.enable_command('upload-photo', this.env.coltypes.photo ? true : false);
+    this.enable_command('delete-photo', this.env.coltypes.photo && id != '-del-');
   };
 
 
@@ -4826,7 +4827,7 @@
       var current_li, target_li;
 
       if ((current_li = this.get_folder_li(old, prefix))) {
-        $(current_li).removeClass('selected').removeClass('unfocused');
+        $(current_li).removeClass('selected').addClass('unfocused');
       }
       if ((target_li = this.get_folder_li(name, prefix))) {
         $(target_li).removeClass('unfocused').addClass('selected');
@@ -4855,17 +4856,18 @@
   // and for setting some message list global variables
   this.set_message_coltypes = function(coltypes, repl)
   {
-    this.env.coltypes = coltypes;
+    var list = this.message_list,
+      thead = list ? list.list.tHead : null,
+      cell, col, n, len, th, tr;
 
-    // set correct list titles
-    var thead = this.gui_objects.messagelist ? this.gui_objects.messagelist.tHead : null,
-      cell, col, n, len;
+    this.env.coltypes = coltypes;
 
     // replace old column headers
     if (thead) {
       if (repl) {
-        var th = document.createElement('thead'),
-          tr = document.createElement('tr');
+        th = document.createElement('thead');
+        tr = document.createElement('tr');
+
         for (c=0, len=repl.length; c < len; c++) {
           cell = document.createElement('td');
           cell.innerHTML = repl[c].html;
@@ -4899,15 +4901,16 @@
 
     if ((n = $.inArray('subject', this.env.coltypes)) >= 0) {
       this.set_env('subject_col', n);
-      if (this.message_list)
-        this.message_list.subject_col = n;
+      if (list)
+        list.subject_col = n;
     }
     if ((n = $.inArray('flag', this.env.coltypes)) >= 0)
       this.set_env('flagged_col', n);
     if ((n = $.inArray('status', this.env.coltypes)) >= 0)
       this.set_env('status_col', n);
 
-    this.message_list.init_header();
+    if (list)
+      list.init_header();
   };
 
   // replace content of row count display
@@ -5076,8 +5079,9 @@
       quota_width = parseInt(quota / 100 * width),
       pos = $(obj).position();
 
-    // Opera bug?
+    // workarounds for Opera and Webkit bugs
     pos.top = Math.max(0, pos.top);
+    pos.left = Math.max(0, pos.left);
 
     this.env.indicator_width = width;
     this.env.indicator_height = height;
@@ -5115,7 +5119,7 @@
       bar1.addClass('quota_mid');
     }
     else {
-      main.addClass(' quota_text_normal');
+      main.addClass(' quota_text_low');
       bar1.addClass('quota_low');
     }
 
@@ -5194,7 +5198,7 @@
       this.set_busy(true);
 
     if (this.is_framed())
-      parent.redirect(url, lock);
+      parent.rcmail.redirect(url, lock);
     else
       this.location_href(url, window);
   };
@@ -5386,7 +5390,7 @@
     this.set_busy(false, null, lock);
     request.abort();
 
-    if (errmsg)
+    if (request.status && errmsg)
       this.display_message(this.get_label('servererror') + ' (' + errmsg + ')', 'error');
   };
 
@@ -5432,14 +5436,7 @@
     if (this.env.keep_alive && !this.env.framed && this.task == 'mail' && this.gui_objects.mailboxlist)
       this._int = setInterval(function(){ ref.check_for_recent(false); }, this.env.keep_alive * 1000);
     else if (this.env.keep_alive && !this.env.framed && this.task != 'login' && this.env.action != 'print')
-      this._int = setInterval(function(){ ref.send_keep_alive(); }, this.env.keep_alive * 1000);
-  };
-
-  // sends keep-alive signal to the server
-  this.send_keep_alive = function()
-  {
-    var d = new Date();
-    this.http_request('keep-alive', '_t='+d.getTime());
+      this._int = setInterval(function(){ ref.http_request('keep-alive'); }, this.env.keep_alive * 1000);
   };
 
   // sends request to check for recent messages
@@ -5448,7 +5445,7 @@
     if (this.busy)
       return;
 
-    var lock, addurl = '_t=' + (new Date().getTime()) + '&_mbox=' + urlencode(this.env.mailbox);
+    var lock, addurl = '_mbox=' + urlencode(this.env.mailbox);
 
     if (refresh) {
       lock = this.set_busy(true, 'checkingmail');

--
Gitblit v1.9.1