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)

---
 index.php         |    2 +-
 program/js/app.js |   23 ++++++++++++++++++++++-
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/index.php b/index.php
index 4763501..a1e957d 100644
--- a/index.php
+++ b/index.php
@@ -211,7 +211,7 @@
         $OUTPUT->show_message('sessionerror', 'error', null, true, -1);
     }
 
-    if ($OUTPUT->ajax_call || !empty($_REQUEST['_framed'])) {
+    if ($OUTPUT->ajax_call || $OUTPUT->get_env('framed')) {
         $OUTPUT->command('session_error', $RCMAIL->url(array('_err' => 'session')));
         $OUTPUT->send('iframe');
     }
diff --git a/program/js/app.js b/program/js/app.js
index 25f7b1e..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);
@@ -3261,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(){
@@ -3655,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()
@@ -3679,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
@@ -4216,6 +4235,7 @@
   this.sent_successfully = function(type, msg, folders)
   {
     this.display_message(msg, type);
+    this.compose_skip_unsavedcheck = true;
 
     if (this.env.extwin) {
       this.lock_form(this.gui_objects.messageform);
@@ -7131,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