From 77799d87ba05a8e96d604693dcfa003b5835fe2b Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Fri, 27 Apr 2012 03:24:24 -0400
Subject: [PATCH] - Applied some fixes from trunk

---
 CHANGELOG                       |    5 +
 index.php                       |    4 +
 program/include/rcube_vcard.php |   54 +++++++++++++----
 tests/vcards.php                |    2 
 program/steps/mail/sendmail.inc |   20 +++---
 program/js/app.js               |   73 +++++++++++++----------
 6 files changed, 102 insertions(+), 56 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 2b6a3b7..89d89b7 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,11 @@
 CHANGELOG Roundcube Webmail
 ===========================
 
+- Fix redirect to mail/compose on re-login (#1488226)
+- Add IE8 hack for messages list issue (#1487821)
+- Fix handling errors on draft auto-save
+- Fix importing vCard photo with ENCODING param specified (#1488432)
+- Fix issue where draft auto-save wasn't executed after some inactivity time
 - Fix lack of warning when switching task in compose window (#1488399)
 - Fix bug where it wasn't possible to enter ( or & characters in autocomplete fields
 - Fix counting of messages search results (on refresh when search filter is in use)
diff --git a/index.php b/index.php
index d874062..8bc5c20 100644
--- a/index.php
+++ b/index.php
@@ -119,6 +119,10 @@
       // prevent endless looping on login page
       if ($query['_task'] == 'login')
         unset($query['_task']);
+
+      // prevent redirect to compose with specified ID (#1488226)
+      if ($query['_action'] == 'compose' && !empty($query['_id']))
+        $query = array();
     }
 
     // allow plugins to control the redirect url after login success
diff --git a/program/include/rcube_vcard.php b/program/include/rcube_vcard.php
index 283da1d..9929d0f 100644
--- a/program/include/rcube_vcard.php
+++ b/program/include/rcube_vcard.php
@@ -292,11 +292,10 @@
       case 'photo':
         if (strpos($value, 'http:') === 0) {
             // TODO: fetch file from URL and save it locally?
-            $this->raw['PHOTO'][0] = array(0 => $value, 'URL' => true);
+            $this->raw['PHOTO'][0] = array(0 => $value, 'url' => true);
         }
         else {
-            $encoded = !preg_match('![^a-z0-9/=+-]!i', $value);
-            $this->raw['PHOTO'][0] = array(0 => $encoded ? $value : base64_encode($value), 'BASE64' => true);
+            $this->raw['PHOTO'][0] = array(0 => $value, 'base64' => (bool) preg_match('![^a-z0-9/=+-]!i', $value));
         }
         break;
 
@@ -549,26 +548,45 @@
       if (preg_match_all('/([^\\;]+);?/', $line[1], $regs2)) {
         $entry = array();
         $field = strtoupper($regs2[1][0]);
+        $enc   = null;
 
         foreach($regs2[1] as $attrid => $attr) {
           if ((list($key, $value) = explode('=', $attr)) && $value) {
             $value = trim($value);
             if ($key == 'ENCODING') {
               // add next line(s) to value string if QP line end detected
-              while ($value == 'QUOTED-PRINTABLE' && preg_match('/=$/', $lines[$i]))
+              if ($value == 'QUOTED-PRINTABLE') {
+                while (preg_match('/=$/', $lines[$i]))
                   $line[2] .= "\n" . $lines[++$i];
-
-              $line[2] = self::decode_value($line[2], $value);
+              }
+              $enc = $value;
             }
-            else
-              $entry[strtolower($key)] = array_merge((array)$entry[strtolower($key)], (array)self::vcard_unquote($value, ','));
+            else {
+              $lc_key = strtolower($key);
+              $entry[$lc_key] = array_merge((array)$entry[$lc_key], (array)self::vcard_unquote($value, ','));
+            }
           }
           else if ($attrid > 0) {
-            $entry[$key] = true;  // true means attr without =value
+            $entry[strtolower($key)] = true;  // true means attr without =value
           }
         }
 
-        $entry = array_merge($entry, (array)self::vcard_unquote($line[2]));
+        // decode value
+        if ($enc || !empty($entry['base64'])) {
+          // save encoding type (#1488432)
+          if ($enc == 'B') {
+            $entry['encoding'] = 'B';
+            // should we use vCard 3.0 instead?
+            // $entry['base64'] = true;
+          }
+          $line[2] = self::decode_value($line[2], $enc ? $enc : 'base64');
+        }
+
+        if ($enc != 'B' && empty($entry['base64'])) {
+          $line[2] = self::vcard_unquote($line[2]);
+        }
+
+        $entry = array_merge($entry, (array) $line[2]);
         $data[$field][] = $entry;
       }
     }
@@ -593,6 +611,7 @@
         return quoted_printable_decode($value);
 
       case 'base64':
+      case 'b':
         self::$values_decoded = true;
         return base64_decode($value);
 
@@ -624,13 +643,20 @@
         if (is_array($entry)) {
           $value = array();
           foreach($entry as $attrname => $attrvalues) {
-            if (is_int($attrname))
+            if (is_int($attrname)) {
+              if (!empty($entry['base64']) || $entry['encoding'] == 'B') {
+                $attrvalues = base64_encode($attrvalues);
+              }
               $value[] = $attrvalues;
-            elseif ($attrvalues === true)
-              $attr .= ";$attrname";    // true means just tag, not tag=value, as in PHOTO;BASE64:...
+            }
+            else if (is_bool($attrvalues)) {
+              if ($attrvalues) {
+                $attr .= strtoupper(";$attrname");    // true means just tag, not tag=value, as in PHOTO;BASE64:...
+              }
+            }
             else {
               foreach((array)$attrvalues as $attrvalue)
-                $attr .= ";$attrname=" . self::vcard_quote($attrvalue, ',');
+                $attr .= strtoupper(";$attrname=") . self::vcard_quote($attrvalue, ',');
             }
           }
         }
diff --git a/program/js/app.js b/program/js/app.js
index 2814639..0db1746 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -269,7 +269,7 @@
         // show printing dialog
         else if (this.env.action == 'print' && this.env.uid)
           if (bw.safari)
-            window.setTimeout('window.print()', 10);
+            setTimeout('window.print()', 10);
           else
             window.print();
 
@@ -746,7 +746,7 @@
       case 'always-load':
         if (this.env.uid && this.env.sender) {
           this.add_contact(urlencode(this.env.sender));
-          window.setTimeout(function(){ ref.command('load-images'); }, 300);
+          setTimeout(function(){ ref.command('load-images'); }, 300);
           break;
         }
 
@@ -764,7 +764,7 @@
             qstring += '&_safe=1';
           this.attachment_win = window.open(this.env.comm_path+'&_action=get&'+qstring+'&_frame=1', 'rcubemailattachment');
           if (this.attachment_win) {
-            window.setTimeout(function(){ ref.attachment_win.focus(); }, 10);
+            setTimeout(function(){ ref.attachment_win.focus(); }, 10);
             break;
           }
         }
@@ -879,19 +879,25 @@
         break;
 
       case 'savedraft':
+        var form = this.gui_objects.messageform, msgid;
+
         // Reset the auto-save timer
-        self.clearTimeout(this.save_timer);
+        clearTimeout(this.save_timer);
 
-        if (!this.gui_objects.messageform)
+        // saving Drafts is disabled
+        if (!form)
           break;
 
-        // if saving Drafts is disabled in main.inc.php
-        // or if compose form did not change
-        if (!this.env.drafts_mailbox || this.cmp_hash == this.compose_field_hash())
+        // compose form did not change
+        if (this.cmp_hash == this.compose_field_hash()) {
+          this.auto_save_start();
           break;
+        }
 
-        var form = this.gui_objects.messageform,
-          msgid = this.set_busy(true, 'savingmessage');
+        // re-set keep-alive timeout
+        this.start_keepalive();
+
+        msgid = this.set_busy(true, 'savingmessage');
 
         form.target = "savetarget";
         form._draft.value = '1';
@@ -907,7 +913,7 @@
           break;
 
         // Reset the auto-save timer
-        self.clearTimeout(this.save_timer);
+        clearTimeout(this.save_timer);
 
         // all checks passed, send message
         var lang = this.spellcheck_lang(),
@@ -926,7 +932,7 @@
 
       case 'send-attachment':
         // Reset the auto-save timer
-        self.clearTimeout(this.save_timer);
+        clearTimeout(this.save_timer);
 
         this.upload_file(props)
         break;
@@ -964,7 +970,7 @@
         if (uid = this.get_single_uid()) {
           ref.printwin = window.open(this.env.comm_path+'&_action=print&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+(this.env.safemode ? '&_safe=1' : ''));
           if (this.printwin) {
-            window.setTimeout(function(){ ref.printwin.focus(); }, 20);
+            setTimeout(function(){ ref.printwin.focus(); }, 20);
             if (this.env.action != 'show')
               this.mark_message('read', uid);
           }
@@ -975,7 +981,7 @@
         if (uid = this.get_single_uid()) {
           ref.sourcewin = window.open(this.env.comm_path+'&_action=viewsource&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox));
           if (this.sourcewin)
-            window.setTimeout(function(){ ref.sourcewin.focus(); }, 20);
+            setTimeout(function(){ ref.sourcewin.focus(); }, 20);
           }
         break;
 
@@ -1120,7 +1126,7 @@
 
     // set timer for requests
     if (a && this.env.request_timeout)
-      this.request_timer = window.setTimeout(function(){ ref.request_timed_out(); }, this.env.request_timeout * 1000);
+      this.request_timer = setTimeout(function(){ ref.request_timed_out(); }, this.env.request_timeout * 1000);
 
     return id;
   };
@@ -1172,7 +1178,7 @@
     if (this.is_framed())
       parent.rcmail.reload(delay);
     else if (delay)
-      window.setTimeout(function(){ rcmail.reload(); }, delay);
+      setTimeout(function(){ rcmail.reload(); }, delay);
     else if (window.location)
       location.href = this.env.comm_path + (this.env.action ? '&_action='+this.env.action : '');
   };
@@ -1305,7 +1311,7 @@
     this.env.last_folder_target = null;
 
     if (this.folder_auto_timer) {
-      window.clearTimeout(this.folder_auto_timer);
+      clearTimeout(this.folder_auto_timer);
       this.folder_auto_timer = null;
       this.folder_auto_expand = null;
     }
@@ -1358,15 +1364,15 @@
             // if the folder is collapsed, expand it after 1sec and restart the drag & drop process.
             if (div.hasClass('collapsed')) {
               if (this.folder_auto_timer)
-                window.clearTimeout(this.folder_auto_timer);
+                clearTimeout(this.folder_auto_timer);
 
               this.folder_auto_expand = this.env.mailboxes[k].id;
-              this.folder_auto_timer = window.setTimeout(function() {
+              this.folder_auto_timer = setTimeout(function() {
                 rcmail.command('collapse-folder', rcmail.folder_auto_expand);
                 rcmail.drag_start(null);
               }, 1000);
             } else if (this.folder_auto_timer) {
-              window.clearTimeout(this.folder_auto_timer);
+              clearTimeout(this.folder_auto_timer);
               this.folder_auto_timer = null;
               this.folder_auto_expand = null;
             }
@@ -1518,7 +1524,7 @@
 
     // start timer for message preview (wait for double click)
     if (selected && this.env.contentframe && !list.multi_selecting && !this.dummy_select)
-      this.preview_timer = window.setTimeout(function(){ ref.msglist_get_preview(); }, 200);
+      this.preview_timer = setTimeout(function(){ ref.msglist_get_preview(); }, 200);
     else if (this.env.contentframe)
       this.show_contentframe(false);
   };
@@ -1535,7 +1541,7 @@
           clearTimeout(this.preview_timer);
         if (this.preview_read_timer)
           clearTimeout(this.preview_read_timer);
-        this.preview_timer = window.setTimeout(function(){ ref.msglist_get_preview(); }, 200);
+        this.preview_timer = setTimeout(function(){ ref.msglist_get_preview(); }, 200);
       }
     }
   };
@@ -1804,8 +1810,11 @@
       else if (c == 'threads')
         html = expando;
       else if (c == 'subject') {
-        if (bw.ie)
+        if (bw.ie) {
           col.onmouseover = function() { rcube_webmail.long_subject_title_ie(this, message.depth+1); };
+          if (bw.ie8)
+            tree = '<span></span>' + tree; // #1487821
+        }
         html = tree + cols[c];
       }
       else if (c == 'priority') {
@@ -1916,7 +1925,7 @@
 
       // mark as read and change mbox unread counter
       if (action == '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 = window.setTimeout(function() {
+        this.preview_read_timer = setTimeout(function() {
           ref.set_message(id, 'unread', false);
           ref.update_thread_root(id, 'read');
           if (ref.env.unread_counts[ref.env.mailbox]) {
@@ -3131,7 +3140,7 @@
   this.auto_save_start = function()
   {
     if (this.env.draft_autosave)
-      this.save_timer = self.setTimeout(function(){ ref.command("savedraft"); }, this.env.draft_autosave * 1000);
+      this.save_timer = setTimeout(function(){ ref.command("savedraft"); }, this.env.draft_autosave * 1000);
 
     // Unlock interface now that saving is complete
     this.busy = false;
@@ -3415,7 +3424,7 @@
 
   this.upload_progress_start = function(action, name)
   {
-    window.setTimeout(function() { rcmail.http_request(action, {_progress: name}); },
+    setTimeout(function() { rcmail.http_request(action, {_progress: name}); },
       this.env.upload_progress_time * 1000);
   };
 
@@ -3515,7 +3524,7 @@
   {
     this.display_message(msg, type);
     // before redirect we need to wait some time for Chrome (#1486177)
-    window.setTimeout(function(){ ref.list_mailbox(); }, 500);
+    setTimeout(function(){ ref.list_mailbox(); }, 500);
   };
 
 
@@ -3573,11 +3582,11 @@
       case 37:  // left
       case 39:  // right
         if (mod != SHIFT_KEY)
-	      return;
+          return;
     }
 
     // start timer
-    this.ksearch_timer = window.setTimeout(function(){ ref.ksearch_get_results(props); }, 200);
+    this.ksearch_timer = setTimeout(function(){ ref.ksearch_get_results(props); }, 200);
     this.ksearch_input = obj;
 
     return true;
@@ -3885,7 +3894,7 @@
       source = this.env.source ? this.env.address_sources[this.env.source] : null;
 
     if (id = list.get_single_selection())
-      this.preview_timer = window.setTimeout(function(){ ref.load_contact(id, 'show'); }, 200);
+      this.preview_timer = setTimeout(function(){ ref.load_contact(id, 'show'); }, 200);
     else if (this.env.contentframe)
       this.show_contentframe(false);
 
@@ -5374,7 +5383,7 @@
       }
       // add element and set timeout
       this.messages[key].elements.push(id);
-      window.setTimeout(function() { ref.hide_message(id, type == 'loading'); }, timeout);
+      setTimeout(function() { ref.hide_message(id, type == 'loading'); }, timeout);
       return id;
     }
 
@@ -5392,7 +5401,7 @@
     }
 
     if (timeout > 0)
-      window.setTimeout(function() { ref.hide_message(id, type == 'loading'); }, timeout);
+      setTimeout(function() { ref.hide_message(id, type == 'loading'); }, timeout);
     return id;
   };
 
diff --git a/program/steps/mail/sendmail.inc b/program/steps/mail/sendmail.inc
index 25eb059..b5d3834 100644
--- a/program/steps/mail/sendmail.inc
+++ b/program/steps/mail/sendmail.inc
@@ -688,17 +688,19 @@
       unlink($mailbody_file);
       $mailbody_file = null;
     }
+  }
 
-    // raise error if saving failed
-    if (!$saved) {
-      raise_error(array('code' => 800, 'type' => 'imap',
-	    'file' => __FILE__, 'line' => __LINE__,
-            'message' => "Could not save message in $store_target"), TRUE, FALSE);
+  // raise error if saving failed
+  if (!$saved) {
+    raise_error(array('code' => 800, 'type' => 'imap',
+       'file' => __FILE__, 'line' => __LINE__,
+       'message' => "Could not save message in $store_target"), TRUE, FALSE);
 
-      if ($savedraft) {
-        $OUTPUT->show_message('errorsaving', 'error');
-        $OUTPUT->send('iframe');
-      }
+    if ($savedraft) {
+      $OUTPUT->show_message('errorsaving', 'error');
+      // start the auto-save timer again
+      $OUTPUT->command('auto_save_start');
+      $OUTPUT->send('iframe');
     }
   }
 
diff --git a/tests/vcards.php b/tests/vcards.php
index ba5ce2b..22f7cdd 100644
--- a/tests/vcards.php
+++ b/tests/vcards.php
@@ -44,7 +44,7 @@
     $input .= file_get_contents($this->_srcpath('johndoe.vcf'));
     
     $vcards = rcube_vcard::import($input);
-    
+
     $this->assertEqual(2, count($vcards), "Detected 2 vcards");
     $this->assertEqual("Apple Computer AG", $vcards[0]->displayname, "FN => displayname");
     $this->assertEqual("John Doƫ", $vcards[1]->displayname, "Displayname with correct charset");

--
Gitblit v1.9.1