diff options
-rw-r--r-- | CHANGELOG | 2 | ||||
-rw-r--r-- | program/include/rcube_message.php | 26 | ||||
-rw-r--r-- | program/include/rcube_session.php | 14 | ||||
-rw-r--r-- | program/js/app.js | 6 | ||||
-rw-r--r-- | program/steps/mail/compose.inc | 3 | ||||
-rw-r--r-- | skins/larry/images/overflowshadow.png | bin | 0 -> 1163 bytes | |||
-rw-r--r-- | skins/larry/includes/mailtoolbar.html | 13 | ||||
-rw-r--r-- | skins/larry/mail.css | 10 | ||||
-rw-r--r-- | skins/larry/styles.css | 46 | ||||
-rw-r--r-- | skins/larry/templates/addressbook.html | 4 | ||||
-rw-r--r-- | skins/larry/templates/compose.html | 5 | ||||
-rw-r--r-- | skins/larry/templates/contactedit.html | 4 | ||||
-rw-r--r-- | skins/larry/templates/folderedit.html | 2 | ||||
-rw-r--r-- | skins/larry/templates/folders.html | 4 | ||||
-rw-r--r-- | skins/larry/templates/identities.html | 4 | ||||
-rw-r--r-- | skins/larry/templates/identityedit.html | 2 | ||||
-rw-r--r-- | skins/larry/templates/mail.html | 14 | ||||
-rw-r--r-- | skins/larry/templates/message.html | 16 | ||||
-rw-r--r-- | skins/larry/templates/settings.html | 6 | ||||
-rw-r--r-- | skins/larry/templates/settingsedit.html | 4 | ||||
-rw-r--r-- | skins/larry/ui.js | 17 |
21 files changed, 153 insertions, 49 deletions
@@ -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 Binary files differnew file mode 100644 index 000000000..54dfdafce --- /dev/null +++ b/skins/larry/images/overflowshadow.png 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()" /> <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'); } |