From 007f1b443888a17b5156ef871e5548d28a3a0130 Mon Sep 17 00:00:00 2001
From: Thomas Bruederli <thomas@roundcube.net>
Date: Sun, 20 Jul 2014 08:00:58 -0400
Subject: [PATCH] Warn for unsent/unsaved message when closing compose window; remove localStorage copy if page was left intentionally but not on session errors (#1489818)

---
 program/js/app.js |   94 ++++++++++++++++++++++++++++++++++++----------
 1 files changed, 73 insertions(+), 21 deletions(-)

diff --git a/program/js/app.js b/program/js/app.js
index d56088d..69cbca8 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -593,6 +593,7 @@
 
       // remove copy from local storage if compose screen is left intentionally
       this.remove_compose_data(this.env.compose_id);
+      this.compose_skip_unsavedcheck = true;
     }
 
     // process external commands
@@ -652,6 +653,7 @@
 
           if (win) {
             this.save_compose_form_local();
+            this.compose_skip_unsavedcheck = true;
             $("input[name='_action']", form).val('compose');
             form.action = this.url('mail/compose', { _id: this.env.compose_id, _extwin: 1 });
             form.target = win.name;
@@ -1325,7 +1327,7 @@
     var url = this.get_task_url(task);
     if (task == 'mail')
       url += '&_mbox=INBOX';
-    else if (task == 'logout')
+    else if (task == 'logout' && !this.env.server_error)
       this.clear_compose_data();
 
     this.redirect(url);
@@ -2064,17 +2066,35 @@
         this.location_href(this.env.comm_path+url, target, true);
 
       // mark as read and change mbox unread counter
-      if (preview && this.message_list && this.message_list.rows[id] && this.message_list.rows[id].unread && this.env.preview_pane_mark_read >= 0) {
+      if (preview && this.message_list && this.message_list.rows[id] && this.message_list.rows[id].unread && this.env.preview_pane_mark_read > 0) {
         this.preview_read_timer = setTimeout(function() {
-          ref.set_message(id, 'unread', false);
-          if (ref.env.unread_counts[ref.env.mailbox]) {
-            ref.env.unread_counts[ref.env.mailbox] -= 1;
-            ref.set_unread_count(ref.env.mailbox, ref.env.unread_counts[ref.env.mailbox], ref.env.mailbox == 'INBOX');
-          }
-          if (ref.env.preview_pane_mark_read > 0)
-            ref.http_post('mark', {_uid: id, _flag: 'read', _quiet: 1});
+          ref.set_unread_message(id, ref.env.mailbox);
+          ref.http_post('mark', {_uid: id, _flag: 'read', _quiet: 1});
         }, this.env.preview_pane_mark_read * 1000);
       }
+    }
+  };
+
+  // update message status and unread counter after marking a message as read
+  this.set_unread_message = function(id, folder)
+  {
+    var self = this;
+
+    // find window with messages list
+    if (!self.message_list)
+      self = self.opener();
+
+    if (!self && window.parent)
+      self = parent.rcmail;
+
+    if (!self || !self.message_list)
+      return;
+
+    self.set_message(id, 'unread', false);
+
+    if (self.env.unread_counts[folder] > 0) {
+      self.env.unread_counts[folder] -= 1;
+      self.set_unread_count(folder, self.env.unread_counts[folder], folder == 'INBOX');
     }
   };
 
@@ -3243,6 +3263,7 @@
     form._draft.value = draft ? '1' : '';
     form.action = this.add_url(form.action, '_unlock', msgid);
     form.action = this.add_url(form.action, '_lang', lang);
+    form.action = this.add_url(form.action, '_framed', 1);
 
     // register timer to notify about connection timeout
     this.submit_timer = setTimeout(function(){
@@ -3537,10 +3558,7 @@
     // submit delete request
     if (key && confirm(this.get_label('deleteresponseconfirm'))) {
       this.http_post('settings/delete-response', { _key: key }, false);
-      return true;
     }
-
-    return false;
   };
 
   this.stop_spellchecking = function()
@@ -3640,6 +3658,7 @@
 
     // always remove local copy upon saving as draft
     this.remove_compose_data(this.env.compose_id);
+    this.compose_skip_unsavedcheck = false;
   };
 
   this.auto_save_start = function()
@@ -3664,6 +3683,21 @@
           ref.compose_type_activity_last = ref.compose_type_activity;
         }
       }, 5000);
+
+      $(window).unload(function() {
+        // remove copy from local storage if compose screen is left after warning
+        if (!ref.env.server_error)
+          ref.remove_compose_data(ref.env.compose_id);
+      });
+    }
+
+    // check for unsaved changes before leaving the compose page
+    if (!window.onbeforeunload) {
+      window.onbeforeunload = function() {
+        if (!ref.compose_skip_unsavedcheck && ref.cmp_hash != ref.compose_field_hash()) {
+          return ref.get_label('notsentwarning');
+        }
+      };
     }
 
     // Unlock interface now that saving is complete
@@ -4201,23 +4235,25 @@
   this.sent_successfully = function(type, msg, folders)
   {
     this.display_message(msg, type);
+    this.compose_skip_unsavedcheck = true;
 
     if (this.env.extwin) {
-      var rc = this.opener();
       this.lock_form(this.gui_objects.messageform);
+
+      var rc = this.opener();
       if (rc) {
         rc.display_message(msg, type);
         // refresh the folder where sent message was saved or replied message comes from
         if (folders && rc.env.task == 'mail' && rc.env.action == '' && $.inArray(rc.env.mailbox, folders) >= 0) {
-          // @TODO: try with 'checkmail' here when #1485186 is fixed. See also #1489249.
-          rc.command('list');
+          rc.command('checkmail');
         }
       }
-      setTimeout(function(){ window.close() }, 1000);
+
+      setTimeout(function() { window.close(); }, 1000);
     }
     else {
       // before redirect we need to wait some time for Chrome (#1486177)
-      setTimeout(function(){ ref.list_mailbox(); }, 500);
+      setTimeout(function() { ref.list_mailbox(); }, 500);
     }
   };
 
@@ -5593,10 +5629,8 @@
       id = this.env.iid ? this.env.iid : selection[0];
 
     // submit request with appended token
-    if (confirm(this.get_label('deleteidentityconfirm')))
-      this.goto_url('delete-identity', { _iid: id, _token: this.env.request_token }, true);
-
-    return true;
+    if (id && confirm(this.get_label('deleteidentityconfirm')))
+      this.http_post('settings/delete-identity', { _iid: id }, true);
   };
 
   this.update_identity_row = function(id, name, add)
@@ -5640,6 +5674,23 @@
         frame.location.href = this.env.blankpage;
       }
     }
+
+    this.enable_command('delete', false);
+  };
+
+  this.remove_identity = function(id)
+  {
+    var frame, list = this.identity_list,
+      rid = this.html_identifier(id);
+
+    if (list && id) {
+      list.remove_row(rid);
+      if (this.env.contentframe && (frame = this.get_frame_window(this.env.contentframe))) {
+        frame.location.href = this.env.blankpage;
+      }
+    }
+
+    this.enable_command('delete', false);
   };
 
 
@@ -7100,6 +7151,7 @@
     // save message in local storage and do not redirect
     if (this.env.action == 'compose') {
       this.save_compose_form_local();
+      this.compose_skip_unsavedcheck = true;
     }
     else if (redirect_url) {
       window.setTimeout(function(){ ref.redirect(redirect_url, true); }, 2000);

--
Gitblit v1.9.1