From d608088a64e961409e9b201fe83d050e7bfb90e3 Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Mon, 25 Mar 2013 14:49:13 -0400
Subject: [PATCH] Fix saving draft just after entering compose window (#1489012)

---
 program/js/app.js |   44 +++++++++++++++++++++++++++++++++++---------
 1 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/program/js/app.js b/program/js/app.js
index 13f1378..87cdf3b 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -178,6 +178,11 @@
       parent.rcmail.env.frame_lock = null;
     }
 
+    // Makes that reference to document.activeElement do not throw
+    // "unspecified error" in IE9 (#1489008)
+    if (this.env.framed && bw.ie)
+      document.documentElement.focus();
+
     // enable general commands
     this.enable_command('close', 'logout', 'mail', 'addressbook', 'settings', 'save-pref', 'compose', 'undo', 'about', 'switch-task', true);
 
@@ -821,7 +826,7 @@
 
         // open attachment in frame if it's of a supported mimetype
         if (this.env.uid && props.mimetype && this.env.mimetypes && $.inArray(props.mimetype, this.env.mimetypes) >= 0) {
-          var attachment_win = window.open(this.env.comm_path+'&_action=get&'+qstring+'&_frame=1', 'rcubemailattachment'+this.env.uid+props.part);
+          var attachment_win = window.open(this.env.comm_path+'&_action=get&'+qstring+'&_frame=1', this.html_identifier('rcubemailattachment'+this.env.uid+props.part));
           if (attachment_win) {
             setTimeout(function(){ attachment_win.focus(); }, 10);
             break;
@@ -944,8 +949,8 @@
         // Reset the auto-save timer
         clearTimeout(this.save_timer);
 
-        // compose form did not change
-        if (this.cmp_hash == this.compose_field_hash()) {
+        // compose form did not change (and draft wasn't saved already)
+        if (this.draft_saved && this.cmp_hash == this.compose_field_hash()) {
           this.auto_save_start();
           break;
         }
@@ -3038,10 +3043,10 @@
       input_message = $("[name='_message']").get(0),
       html_mode = $("input[name='_is_html']").val() == '1',
       ac_fields = ['cc', 'bcc', 'replyto', 'followupto'],
-      ac_props;
+      ac_props, opener_rc = this.opener();
 
     // close compose step in opener
-    if (window.opener && !window.opener.closed && opener.rcmail && opener.rcmail.env.action == 'compose') {
+    if (opener_rc && opener_rc.env.action == 'compose') {
       setTimeout(function(){ opener.history.back(); }, 100);
       this.env.opened_extwin = true;
     }
@@ -3340,6 +3345,7 @@
 
   this.set_draft_id = function(id)
   {
+    this.draft_saved = id;
     $("input[name='_draft_saveid']").val(id);
   };
 
@@ -3720,9 +3726,10 @@
     this.display_message(msg, type);
 
     if (this.env.extwin) {
+      var opener_rc = this.opener();
       this.lock_form(this.gui_objects.messageform);
-      if (window.opener && !window.opener.closed && opener.rcmail)
-        opener.rcmail.display_message(msg, type);
+      if (opener_rc)
+        opener_rc.display_message(msg, type);
       setTimeout(function(){ window.close() }, 1000);
     }
     else {
@@ -4290,7 +4297,7 @@
         this.group_member_change('add', cid, dest, to.id);
       else {
         var lock = this.display_message(this.get_label('copyingcontact'), 'loading'),
-          post_data = {_cid: cid, _source: source, _to: dest, _togid: to.id, _gid: group};
+          post_data = {_cid: cid, _source: this.env.source, _to: dest, _togid: to.id, _gid: group};
 
         this.http_post('copy', post_data, lock);
       }
@@ -4298,7 +4305,7 @@
     // target is an addressbook
     else if (to.id != source) {
       var lock = this.display_message(this.get_label('copyingcontact'), 'loading'),
-        post_data = {_cid: cid, _source: source, _to: to.id, _gid: group};
+        post_data = {_cid: cid, _source: this.env.source, _to: to.id, _gid: group};
 
       this.http_post('copy', post_data, lock);
     }
@@ -6349,6 +6356,14 @@
     if (location_url && this.env.action != 'compose')  // don't redirect on compose screen, contents might get lost (#1488926)
       this.redirect(location_url);
 
+    // 403 Forbidden response (CSRF prevention) - reload the page.
+    // In case there's a new valid session it will be used, otherwise
+    // login form will be presented (#1488960).
+    if (request.status == 403) {
+      (this.is_framed() ? parent : window).location.reload();
+      return;
+    }
+
     // re-send keep-alive requests after 30 seconds
     if (action == 'keep-alive')
       setTimeout(function(){ ref.keep_alive(); ref.start_keepalive(); }, 30000);
@@ -6601,6 +6616,17 @@
   /*********            helper methods            *********/
   /********************************************************/
 
+  // get window.opener.rcmail if available
+  this.opener = function()
+  {
+    // catch Error: Permission denied to access property rcmail
+    try {
+      if (window.opener && !opener.closed && opener.rcmail)
+        return opener.rcmail;
+    }
+    catch (e) {}
+  };
+
   // check if we're in show mode or if we have a unique selection
   // and return the message uid
   this.get_single_uid = function()

--
Gitblit v1.9.1