From 3f9518f0a7e49ec259299093ae63f7de5b2f430e Mon Sep 17 00:00:00 2001
From: Thomas Bruederli <thomas@roundcube.net>
Date: Thu, 12 Jul 2012 05:25:22 -0400
Subject: [PATCH] Merge branch 'release-0.8' of github.com:roundcube/roundcubemail into release-0.8

---
 CHANGELOG                               |    2 
 skins/larry/includes/mailtoolbar.html   |   13 +--
 skins/larry/templates/addressbook.html  |    4 
 program/steps/mail/compose.inc          |    3 
 skins/larry/templates/message.html      |   16 ++-
 skins/larry/templates/contactedit.html  |    4 
 skins/larry/templates/folders.html      |    4 
 program/include/rcube_session.php       |   14 ++-
 skins/larry/templates/identities.html   |    4 
 program/include/rcube_message.php       |   26 ++++++
 skins/larry/templates/settingsedit.html |    4 
 skins/larry/templates/identityedit.html |    2 
 skins/larry/templates/folderedit.html   |    2 
 skins/larry/templates/mail.html         |   14 ++-
 skins/larry/templates/settings.html     |    6 +
 skins/larry/styles.css                  |   46 ++++++++++-
 program/js/app.js                       |    6 +
 skins/larry/images/overflowshadow.png   |    0 
 skins/larry/mail.css                    |   10 +
 skins/larry/templates/compose.html      |    5 +
 skins/larry/ui.js                       |   17 ++++
 21 files changed, 153 insertions(+), 49 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 268baa7..f155a0c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,8 @@
 CHANGELOG Roundcube Webmail
 ===========================
 
+- Don't add attachments content into reply/forward/draft message body (#1488557)
+- Fix 'no connection' errors on page unloads (#1488547)
 - Plugin API: Add 'unauthenticated' hook (#1488138)
 - Show explicit error message when provided hostname is invalid (#1488550)
 - Fix wrong compose screen elements focus in IE9 (#1488541)
diff --git a/program/include/rcube_message.php b/program/include/rcube_message.php
index 8f1432f..745019e 100644
--- a/program/include/rcube_message.php
+++ b/program/include/rcube_message.php
@@ -278,6 +278,32 @@
 
 
     /**
+     * Checks if part of the message is an attachment (or part of it)
+     *
+     * @param rcube_message_part $part Message part
+     *
+     * @return bool True if the part is an attachment part
+     */
+    public function is_attachment($part)
+    {
+        foreach ($this->attachments as $att_part) {
+            if ($att_part->mime_id == $part->mime_id) {
+                return true;
+            }
+
+            // check if the part is a subpart of another attachment part (message/rfc822)
+            if ($att_part->mimetype == 'message/rfc822') {
+                if (in_array($part, (array)$att_part->parts)) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+
+    /**
      * Read the message structure returend by the IMAP server
      * and build flat lists of content parts and attachments
      *
diff --git a/program/include/rcube_session.php b/program/include/rcube_session.php
index 4ac3954..6916e2b 100644
--- a/program/include/rcube_session.php
+++ b/program/include/rcube_session.php
@@ -221,13 +221,14 @@
    * Handler for session_destroy()
    *
    * @param string Session ID
+   *
    * @return boolean True on success
    */
   public function db_destroy($key)
   {
-    $this->db->query(
-      sprintf("DELETE FROM %s WHERE sess_id = ?", get_table_name('session')),
-      $key);
+    if ($key) {
+      $this->db->query(sprintf("DELETE FROM %s WHERE sess_id = ?", get_table_name('session')), $key);
+    }
 
     return true;
   }
@@ -308,11 +309,16 @@
    * Handler for session_destroy() with memcache backend
    *
    * @param string Session ID
+   *
    * @return boolean True on success
    */
   public function mc_destroy($key)
   {
-    return $this->memcache->delete($key);
+    if ($key) {
+      $this->memcache->delete($key);
+    }
+
+    return true;
   }
 
 
diff --git a/program/js/app.js b/program/js/app.js
index 8d02f6f..ae9f4e97 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -60,6 +60,8 @@
     beforeSend: function(xmlhttp){ xmlhttp.setRequestHeader('X-Roundcube-Request', ref.env.request_token); }
   });
 
+  $(window).bind('beforeunload', function() { rcmail.unload = true; });
+
   // set environment variable(s)
   this.set_env = function(p, value)
   {
@@ -6129,6 +6131,10 @@
     this.set_busy(false, null, lock);
     request.abort();
 
+    // don't display error message on page unload (#1488547)
+    if (this.unload)
+      return;
+
     if (request.status && errmsg)
       this.display_message(this.get_label('servererror') + ' (' + errmsg + ')', 'error');
     else if (status == 'timeout')
diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc
index 8152f5d..8a47157 100644
--- a/program/steps/mail/compose.inc
+++ b/program/steps/mail/compose.inc
@@ -632,7 +632,8 @@
 
     if (!empty($MESSAGE->parts)) {
       foreach ($MESSAGE->parts as $part) {
-        if ($part->type != 'content' || !$part->size) {
+        // skip no-content and attachment parts (#1488557)
+        if ($part->type != 'content' || !$part->size || $MESSAGE->is_attachment($part)) {
           continue;
         }
 
diff --git a/skins/larry/images/overflowshadow.png b/skins/larry/images/overflowshadow.png
new file mode 100644
index 0000000..54dfdaf
--- /dev/null
+++ b/skins/larry/images/overflowshadow.png
Binary files differ
diff --git a/skins/larry/includes/mailtoolbar.html b/skins/larry/includes/mailtoolbar.html
index fbc2e5e..f750e06 100644
--- a/skins/larry/includes/mailtoolbar.html
+++ b/skins/larry/includes/mailtoolbar.html
@@ -1,15 +1,11 @@
-<div id="mailtoolbar" class="toolbar">
-<roundcube:if condition="template:name == 'message'" />
-<roundcube:button command="list" type="link" class="button back disabled" classAct="button back" classSel="button back pressed" label="back" />
-<roundcube:endif />
 <roundcube:button command="reply" type="link" class="button reply disabled" classAct="button reply" classSel="button reply pressed" label="reply" title="replytomessage" />
 <span class="dropbutton">
-<roundcube:button command="reply-all" type="link" class="button reply-all disabled" classAct="button reply-all" classSel="button reply-all pressed" label="replyall" title="replytoallmessage" />
-<span class="dropbuttontip" id="replyallmenulink" onclick="UI.show_popup('replyallmenu');return false"></span>
+	<roundcube:button command="reply-all" type="link" class="button reply-all disabled" classAct="button reply-all" classSel="button reply-all pressed" label="replyall" title="replytoallmessage" />
+	<span class="dropbuttontip" id="replyallmenulink" onclick="UI.show_popup('replyallmenu');return false"></span>
 </span>
 <span class="dropbutton">
-<roundcube:button command="forward" type="link" class="button forward disabled" classAct="button forward" classSel="button forward pressed" label="forward" title="forwardmessage" />
-<span class="dropbuttontip" id="forwardmenulink" onclick="UI.show_popup('forwardmenu');return false"></span>
+	<roundcube:button command="forward" type="link" class="button forward disabled" classAct="button forward" classSel="button forward pressed" label="forward" title="forwardmessage" />
+	<span class="dropbuttontip" id="forwardmenulink" onclick="UI.show_popup('forwardmenu');return false"></span>
 </span>
 <roundcube:button command="delete" type="link" class="button delete disabled" classAct="button delete" classSel="button delete pressed" label="delete" title="deletemessage" />
 <roundcube:if condition="template:name == 'message'" />
@@ -20,7 +16,6 @@
 <roundcube:button name="markmenulink" id="markmessagemenulink" type="link" class="button markmessage" label="mark" title="markmessages" onclick="UI.show_popup('markmessagemenu');return false" />
 <roundcube:endif />
 <roundcube:button name="messagemenulink" id="messagemenulink" type="link" class="button more" label="more" title="moreactions" onclick="UI.show_popup('messagemenu');return false" />
-</div>
 
 <div id="forwardmenu" class="popupmenu">
 	<ul class="toolbarmenu">
diff --git a/skins/larry/mail.css b/skins/larry/mail.css
index 437c8f1..512fb41 100644
--- a/skins/larry/mail.css
+++ b/skins/larry/mail.css
@@ -18,6 +18,7 @@
 	left: 0;
 	width: 220px;
 	bottom: 0;
+	z-index: 2;
 }
 
 #mailview-right {
@@ -26,6 +27,7 @@
 	left: 232px;
 	right: 0;
 	bottom: 0;
+	z-index: 3;
 }
 
 #mailview-top {
@@ -332,7 +334,6 @@
 	width: 100%;
 }
 
-#mailboxtoolbar,
 #messagetoolbar {
 	position: absolute;
 	top: -6px;
@@ -340,14 +341,17 @@
 	left: 0;
 	height: 40px;
 	white-space: nowrap;
+	z-index: 10;
 }
 
 #messagetoolbar.fullwidth {
 	right: 0;
 }
 
-#mailboxtoolbar {
-	right: 0;
+#messagetoolbar .toolbarselect {
+	position: absolute;
+	bottom: 6px;
+	right: 3px;
 }
 
 #messagesearchtools {
diff --git a/skins/larry/styles.css b/skins/larry/styles.css
index e793fab..341de90 100644
--- a/skins/larry/styles.css
+++ b/skins/larry/styles.css
@@ -654,6 +654,15 @@
 	background: #fff;
 }
 
+.minwidth {
+	position: absolute;
+	top: 0;
+	left: 0;
+	bottom: 0;
+	width: 100%;
+	min-width: 1150px;
+}
+
 .scroller {
 	overflow: auto;
 }
@@ -1036,8 +1045,8 @@
 	margin: 38px 0 10px 0;
 }
 
-body.iframe.footerbuttons {
-	margin-bottom: 42px;
+body.iframe.floatingbuttons {
+	margin-bottom: 40px;
 }
 
 body.iframe.fullheight {
@@ -1064,14 +1073,25 @@
 	z-index: 100;
 }
 
-body.iframe .footerbuttons {
+body.iframe .footerleft.floating {
 	position: fixed;
 	left: 0;
 	bottom: 0;
 	width: 100%;
 	z-index: 110;
 	background: #fff;
-	padding: 8px;
+	padding-top: 8px;
+	padding-bottom: 12px;
+}
+
+body.iframe .footerleft.floating:before {
+	content: " ";
+	position: absolute;
+	top: -6px;
+	left: 0;
+	width: 100%;
+	height: 6px;
+	background: url(images/overflowshadow.png) top center no-repeat;
 }
 
 .boxcontent {
@@ -1087,8 +1107,16 @@
 	overflow: auto;
 }
 
+.iframebox {
+	position: absolute;
+	top: 0;
+	left: 0;
+	right: 0;
+	bottom: 28px;
+}
+
 .footerleft {
-	padding: 0 12px 10px 12px;
+	padding: 0 12px 4px 12px;
 }
 
 .propform fieldset {
@@ -1308,6 +1336,13 @@
 
 
 /*** toolbar ***/
+
+.toolbar .spacer {
+	display: inline-block;
+	width: 24px;
+	height: 40px;
+	padding: 0;
+}
 
 .toolbar a.button {
 	text-align: center;
@@ -1952,6 +1987,7 @@
 	margin-bottom: 12px;
 	padding-top: 15px;
 	height: 27px;
+	white-space: nowrap;
 }
 
 .tabsbar .tablink {
diff --git a/skins/larry/templates/addressbook.html b/skins/larry/templates/addressbook.html
index b379609..ee92ff4 100644
--- a/skins/larry/templates/addressbook.html
+++ b/skins/larry/templates/addressbook.html
@@ -67,7 +67,9 @@
 
 
 <div id="contacts-box" class="uibox">
-	<roundcube:object name="addressframe" id="contact-frame" style="width:100%; height:96%" frameborder="0" src="/watermark.html" />
+	<div class="iframebox">
+		<roundcube:object name="addressframe" id="contact-frame" style="width:100%; height:100%" frameborder="0" src="/watermark.html" />
+	</div>
 	<roundcube:object name="message" id="message" class="statusbar" />
 </div>
 
diff --git a/skins/larry/templates/compose.html b/skins/larry/templates/compose.html
index a71e820..de371b3 100644
--- a/skins/larry/templates/compose.html
+++ b/skins/larry/templates/compose.html
@@ -7,8 +7,9 @@
 <link rel="stylesheet" type="text/css" href="/googiespell.css" />
 <roundcube:endif />
 </head>
-<body class="noscroll">
+<body>
 
+<div class="minwidth">
 <roundcube:include file="/includes/header.html" />
 
 <div id="mainscreen">
@@ -169,6 +170,8 @@
 
 </div><!-- end mainscreen -->
 
+</div><!-- end minwidth -->
+
 <div id="upload-dialog" class="propform popupdialog" title="<roundcube:label name='addattachment' />">
 	<roundcube:object name="composeAttachmentForm" id="uploadform" attachmentFieldSize="40" buttons="no" />
 	<div class="formbuttons">
diff --git a/skins/larry/templates/contactedit.html b/skins/larry/templates/contactedit.html
index 39d4844..2f0c111 100644
--- a/skins/larry/templates/contactedit.html
+++ b/skins/larry/templates/contactedit.html
@@ -4,7 +4,7 @@
 <title><roundcube:object name="pagetitle" /></title>
 <roundcube:include file="/includes/links.html" />
 </head>
-<body class="iframe footerbuttons">
+<body class="iframe">
 
 <h1 class="boxtitle">
 	<roundcube:if condition="env:action=='add'" /><roundcube:label name="addcontact" />
@@ -35,7 +35,7 @@
 
 </form>
 
-<div class="footerbuttons formbuttons">
+<div class="footerleft formbuttons">
 	<roundcube:button command="save" type="input" class="button mainaction" label="save" />
 	<roundcube:button command="show" type="input" class="button" label="cancel" condition="env:action=='edit'" />
 	<roundcube:button name="cancel" type="input" class="button" label="cancel" onclick="history.back()" condition="env:action=='add'" />
diff --git a/skins/larry/templates/folderedit.html b/skins/larry/templates/folderedit.html
index cfc8bc3..18d2469 100644
--- a/skins/larry/templates/folderedit.html
+++ b/skins/larry/templates/folderedit.html
@@ -12,13 +12,11 @@
 <roundcube:object name="folderdetails" class="propform" />
 </div>
 
-<div id="formfooter">
 <div class="footerleft formbuttons">
 	<roundcube:button command="save" type="input" class="button mainaction" label="save" />
 	<roundcube:if condition="!strlen(request:_mbox)" />
 	<input type="button" value="<roundcube:label name="cancel" />" class="button" onclick="history.back()" />&nbsp;
 	<roundcube:endif />
-</div>
 </div>
 
 <roundcube:include file="/includes/footer.html" />
diff --git a/skins/larry/templates/folders.html b/skins/larry/templates/folders.html
index ab4e46c..988ff95 100644
--- a/skins/larry/templates/folders.html
+++ b/skins/larry/templates/folders.html
@@ -28,7 +28,9 @@
 </div>
 
 <div id="folder-details" class="uibox contentbox">
-	<roundcube:object name="folderframe" id="preferences-frame" style="width:100%; height:96%" frameborder="0" src="/watermark.html" />
+	<div class="iframebox">
+		<roundcube:object name="folderframe" id="preferences-frame" style="width:100%; height:100%" frameborder="0" src="/watermark.html" />
+	</div>
 	<roundcube:object name="message" id="message" class="statusbar" />
 </div>
 
diff --git a/skins/larry/templates/identities.html b/skins/larry/templates/identities.html
index 061088e..d9270b6 100644
--- a/skins/larry/templates/identities.html
+++ b/skins/larry/templates/identities.html
@@ -25,7 +25,9 @@
 </div>
 
 <div id="identity-details" class="uibox contentbox">
-	<roundcube:object name="identityframe" id="preferences-frame" style="width:100%; height:96%" frameborder="0" src="/watermark.html" />
+	<div class="iframebox">
+		<roundcube:object name="identityframe" id="preferences-frame" style="width:100%; height:100%" frameborder="0" src="/watermark.html" />
+	</div>
 	<roundcube:object name="message" id="message" class="statusbar" />
 </div>
 
diff --git a/skins/larry/templates/identityedit.html b/skins/larry/templates/identityedit.html
index 3ef4131..8d5e622 100644
--- a/skins/larry/templates/identityedit.html
+++ b/skins/larry/templates/identityedit.html
@@ -12,10 +12,8 @@
 <roundcube:object name="identityform" class="propform" size="40" textareacols="40" textarearows="6" />
 </div>
 
-<div id="formfooter">
 <div class="footerleft formbuttons">
 	<roundcube:button command="save" type="input" class="button mainaction" label="save" />
-</div>
 </div>
 
 <roundcube:include file="/includes/footer.html" />
diff --git a/skins/larry/templates/mail.html b/skins/larry/templates/mail.html
index 01a5986..f6b53f2 100644
--- a/skins/larry/templates/mail.html
+++ b/skins/larry/templates/mail.html
@@ -11,19 +11,22 @@
 <roundcube:endif />
 </style>
 </head>
-<body class="noscroll">
+<body>
 
+<div class="minwidth">
 <roundcube:include file="/includes/header.html" />
 
 <div id="mainscreen">
 
-<div id="mailview-left">
-
 <!-- toolbar -->
-<div id="mailboxtoolbar" class="toolbar">
+<div id="messagetoolbar" class="toolbar">
 	<roundcube:button command="checkmail" type="link" class="button checkmail disabled" classAct="button checkmail" classSel="button checkmail pressed" label="refresh" title="checkmail" />
 	<roundcube:button command="compose" type="link" class="button compose disabled" classAct="button compose" classSel="button compose pressed" label="compose" title="writenewmessage" />
+	<span class="spacer"></span>
+	<roundcube:include file="/includes/mailtoolbar.html" />
 </div>
+
+<div id="mailview-left">
 
 <!-- folders list -->
 <div id="folderlist-header"></div>
@@ -45,7 +48,6 @@
 
 <!-- toolbar -->
 <div id="messagetoolbar">
-<roundcube:include file="/includes/mailtoolbar.html" />
 </div>
 
 <div id="messagesearchtools">
@@ -128,6 +130,8 @@
 
 </div><!-- end mainscreen -->
 
+<div><!-- end minwidth -->
+
 <div id="searchmenu" class="popupmenu">
 	<ul class="toolbarmenu">
 		<li><label><input type="checkbox" name="s_mods[]" value="subject" id="s_mod_subject" onclick="UI.set_searchmod(this)" /> <roundcube:label name="subject" /></label></li>
diff --git a/skins/larry/templates/message.html b/skins/larry/templates/message.html
index 2509662..b66d821 100644
--- a/skins/larry/templates/message.html
+++ b/skins/larry/templates/message.html
@@ -10,8 +10,17 @@
 
 <div id="mainscreen">
 
+<!-- toolbar -->
+<div id="messagetoolbar" class="toolbar fullwidth">
+	<roundcube:button command="list" type="link" class="button back disabled" classAct="button back" classSel="button back pressed" label="back" />
+	<span class="spacer"></span>
+	<roundcube:include file="/includes/mailtoolbar.html" />
+	<div class="toolbarselect">
+		<roundcube:object name="mailboxlist" type="select" noSelection="moveto" maxlength="25" onchange="rcmail.command('moveto', this.options[this.selectedIndex].value)" class="mailboxlist decorated" folder_filter="mail" />
+	</div>
+</div>
+
 <div id="mailview-left">
-<roundcube:object name="mailboxlist" type="select" noSelection="moveto" maxlength="25" onchange="rcmail.command('moveto', this.options[this.selectedIndex].value)" class="mailboxlist" folder_filter="mail" />
 
 <!-- folders list -->
 <div id="mailboxcontainer" class="uibox listbox">
@@ -23,11 +32,6 @@
 </div>
 
 <div id="mailview-right">
-
-<!-- toolbar -->
-<div id="messagetoolbar" class="fullwidth">
-<roundcube:include file="/includes/mailtoolbar.html" />
-</div>
 
 <div id="mailview-top">
 <div id="messageheader" class="uibox">
diff --git a/skins/larry/templates/settings.html b/skins/larry/templates/settings.html
index 88b6b96..427e0a4 100644
--- a/skins/larry/templates/settings.html
+++ b/skins/larry/templates/settings.html
@@ -21,8 +21,10 @@
 </div>
 
 <div id="preferences-box" class="uibox contentbox">
-<roundcube:object name="prefsframe" id="preferences-frame" style="width:100%; height:96%" frameborder="0" src="/watermark.html" />
-<roundcube:object name="message" id="message" class="statusbar" />
+	<div class="iframebox">
+		<roundcube:object name="prefsframe" id="preferences-frame" style="width:100%; height:100%" frameborder="0" src="/watermark.html" />
+	</div>
+	<roundcube:object name="message" id="message" class="statusbar" />
 </div>
 
 </div>
diff --git a/skins/larry/templates/settingsedit.html b/skins/larry/templates/settingsedit.html
index ada5b57..1a80f58 100644
--- a/skins/larry/templates/settingsedit.html
+++ b/skins/larry/templates/settingsedit.html
@@ -12,10 +12,8 @@
 <roundcube:object name="userprefs" form="form" class="propform" />
 </div>
 
-<div id="formfooter">
 <div class="footerleft formbuttons">
-<roundcube:button command="save" type="input" class="button mainaction" label="save" />
-</div>
+	<roundcube:button command="save" type="input" class="button mainaction" label="save" />
 </div>
 
 <roundcube:include file="/includes/footer.html" />
diff --git a/skins/larry/ui.js b/skins/larry/ui.js
index 4872a10..906db1d 100644
--- a/skins/larry/ui.js
+++ b/skins/larry/ui.js
@@ -220,6 +220,7 @@
 
     // don't use $(window).resize() due to some unwanted side-effects
     window.onresize = resize;
+    resize();
   }
 
   /**
@@ -257,6 +258,20 @@
     if (rcmail.env.task == 'mail' && rcmail.env.action == 'compose') {
       layout_composeview();
     }
+
+    // make iframe footer buttons float if scrolling is active
+    $('body.iframe .footerleft').each(function(){
+      var footer = $(this),
+        body = $(document.body),
+        floating = footer.hasClass('floating'),
+        overflow = body.outerHeight(true) > $(window).height();
+      if (overflow != floating) {
+        var action = overflow ? 'addClass' : 'removeClass';
+        footer[action]('floating');
+        body[action]('floatingbuttons');
+      }
+    })
+
   }
 
   /**
@@ -265,7 +280,7 @@
   function message_displayed(p)
   {
     // show a popup dialog on errors
-    if (p.type == 'error') {
+    if (p.type == 'error' && rcmail.env.task != 'login') {
       if (!me.messagedialog) {
         me.messagedialog = $('<div>').addClass('popupdialog');
       }

--
Gitblit v1.9.1