summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG2
-rw-r--r--program/include/rcube_message.php26
-rw-r--r--program/include/rcube_session.php14
-rw-r--r--program/js/app.js6
-rw-r--r--program/steps/mail/compose.inc3
-rw-r--r--skins/larry/images/overflowshadow.pngbin0 -> 1163 bytes
-rw-r--r--skins/larry/includes/mailtoolbar.html13
-rw-r--r--skins/larry/mail.css10
-rw-r--r--skins/larry/styles.css46
-rw-r--r--skins/larry/templates/addressbook.html4
-rw-r--r--skins/larry/templates/compose.html5
-rw-r--r--skins/larry/templates/contactedit.html4
-rw-r--r--skins/larry/templates/folderedit.html2
-rw-r--r--skins/larry/templates/folders.html4
-rw-r--r--skins/larry/templates/identities.html4
-rw-r--r--skins/larry/templates/identityedit.html2
-rw-r--r--skins/larry/templates/mail.html14
-rw-r--r--skins/larry/templates/message.html16
-rw-r--r--skins/larry/templates/settings.html6
-rw-r--r--skins/larry/templates/settingsedit.html4
-rw-r--r--skins/larry/ui.js17
21 files changed, 153 insertions, 49 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 268baa7e9..f155a0c38 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 8f1432fb8..745019e18 100644
--- a/program/include/rcube_message.php
+++ b/program/include/rcube_message.php
@@ -278,6 +278,32 @@ class rcube_message
/**
+ * 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 4ac395472..6916e2ba8 100644
--- a/program/include/rcube_session.php
+++ b/program/include/rcube_session.php
@@ -221,13 +221,14 @@ class rcube_session
* 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 @@ class rcube_session
* 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 8d02f6f39..ae9f4e972 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -60,6 +60,8 @@ function rcube_webmail()
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 @@ function rcube_webmail()
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 8152f5dca..8a4715715 100644
--- a/program/steps/mail/compose.inc
+++ b/program/steps/mail/compose.inc
@@ -632,7 +632,8 @@ function rcmail_prepare_message_body()
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 000000000..54dfdafce
--- /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 fbc2e5e64..f750e061a 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 437c8f15c..512fb41d8 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 @@ a.iconbutton.threadmode.selected {
width: 100%;
}
-#mailboxtoolbar,
#messagetoolbar {
position: absolute;
top: -6px;
@@ -340,14 +341,17 @@ a.iconbutton.threadmode.selected {
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 e793fabbb..341de9008 100644
--- a/skins/larry/styles.css
+++ b/skins/larry/styles.css
@@ -654,6 +654,15 @@ a.iconlink.upload {
background: #fff;
}
+.minwidth {
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ width: 100%;
+ min-width: 1150px;
+}
+
.scroller {
overflow: auto;
}
@@ -1036,8 +1045,8 @@ body.iframe {
margin: 38px 0 10px 0;
}
-body.iframe.footerbuttons {
- margin-bottom: 42px;
+body.iframe.floatingbuttons {
+ margin-bottom: 40px;
}
body.iframe.fullheight {
@@ -1064,14 +1073,25 @@ body.iframe .boxtitle {
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 @@ body.iframe .footerbuttons {
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 {
@@ -1309,6 +1337,13 @@ ul.proplist li {
/*** toolbar ***/
+.toolbar .spacer {
+ display: inline-block;
+ width: 24px;
+ height: 40px;
+ padding: 0;
+}
+
.toolbar a.button {
text-align: center;
font-size: 10px;
@@ -1952,6 +1987,7 @@ ul.toolbarmenu li span.conversation {
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 b379609f5..ee92ff4dc 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 a71e82043..de371b36a 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 39d48440b..2f0c1111b 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 cfc8bc3d4..18d246942 100644
--- a/skins/larry/templates/folderedit.html
+++ b/skins/larry/templates/folderedit.html
@@ -12,14 +12,12 @@
<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 ab4e46ce1..988ff952c 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 061088ea5..d9270b68a 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 3ef41319a..8d5e62290 100644
--- a/skins/larry/templates/identityedit.html
+++ b/skins/larry/templates/identityedit.html
@@ -12,11 +12,9 @@
<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 01a59861c..f6b53f2f8 100644
--- a/skins/larry/templates/mail.html
+++ b/skins/larry/templates/mail.html
@@ -11,20 +11,23 @@
<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>
<div id="mailboxcontainer" class="uibox listbox">
@@ -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 2509662fe..b66d82140 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">
@@ -24,11 +33,6 @@
<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">
<h2 class="subject"><roundcube:object name="messageHeaders" valueOf="subject" /></h2>
diff --git a/skins/larry/templates/settings.html b/skins/larry/templates/settings.html
index 88b6b96b2..427e0a4f5 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 ada5b57ee..1a80f58e9 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 4872a1004..906db1d52 100644
--- a/skins/larry/ui.js
+++ b/skins/larry/ui.js
@@ -220,6 +220,7 @@ function rcube_mail_ui()
// don't use $(window).resize() due to some unwanted side-effects
window.onresize = resize;
+ resize();
}
/**
@@ -257,6 +258,20 @@ function rcube_mail_ui()
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 rcube_mail_ui()
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');
}