summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG6
-rw-r--r--config/defaults.inc.php2
-rw-r--r--installer/config.php3
-rw-r--r--plugins/legacy_browser/js/iehacks.js20
-rw-r--r--plugins/legacy_browser/legacy_browser.php19
-rw-r--r--plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php9
-rw-r--r--plugins/managesieve/managesieve.js29
-rw-r--r--plugins/zipdownload/README3
-rw-r--r--plugins/zipdownload/composer.json9
-rw-r--r--plugins/zipdownload/config.inc.php.dist3
-rw-r--r--plugins/zipdownload/localization/en_US.inc9
-rw-r--r--plugins/zipdownload/package.xml17
-rw-r--r--plugins/zipdownload/zipdownload.js116
-rw-r--r--plugins/zipdownload/zipdownload.php183
-rw-r--r--program/include/rcmail.php2
-rw-r--r--program/include/rcmail_output_html.php19
-rw-r--r--program/js/app.js39
-rw-r--r--program/js/common.js61
-rw-r--r--program/js/list.js4
-rw-r--r--program/lib/Roundcube/rcube_csv2vcard.php2
-rw-r--r--program/lib/Roundcube/rcube_imap.php32
-rw-r--r--program/steps/mail/get.inc4
-rw-r--r--program/steps/mail/import.inc113
-rw-r--r--program/steps/mail/viewsource.inc4
-rw-r--r--program/steps/settings/func.inc2
-rw-r--r--skins/classic/common.css5
26 files changed, 427 insertions, 288 deletions
diff --git a/CHANGELOG b/CHANGELOG
index a32aeabb7..6482ca221 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,8 @@
CHANGELOG Roundcube Webmail
===========================
+- Support messages import from zip archives
+- Zipdownload: Added mbox format support (#1486069)
- Drop support for IE6, move IE7/IE8 support to legacy_browser plugin
- Update to jQuery-2.1.0
- Search across multiple folders (#1485234)
@@ -10,12 +12,16 @@ CHANGELOG Roundcube Webmail
- Set In-Reply-To and References for forwarded messages (#1489593)
- Removed redundant default_folders config option (#1489737)
- Implemented IMAP SPECIAL-USE extension support [RFC6154] (#1487830)
+- Fix mbox files import
- Fix bug where "With attachment" option in search filter wasn't selected after return from mail view (#1489774)
- Fix "washing" of unicoded style attributes (#1489777)
- Fix unintentional redirect from compose page in Webkit browsers (#1489789)
- Fix messages index cache update under some conditions (e.g. proxy) (#1489756)
- Fix lack of translation of special folders in some configurations (#1489799)
- Fix XSS issue in plain text spellchecker (#1489806)
+- Fix invalid page title for some folders (1489804)
+- Fix redundant alert message on over-size uploads (#1489817)
+- Fix next message display after removing a message (#1489800)
RELEASE 1.0.0
-------------
diff --git a/config/defaults.inc.php b/config/defaults.inc.php
index 5c5fccb1e..7f65b9748 100644
--- a/config/defaults.inc.php
+++ b/config/defaults.inc.php
@@ -56,7 +56,7 @@ $config['db_table_dsn'] = array(
// LOGGING/DEBUGGING
// ----------------------------------
-// system error reporting, sum of: 1 = log; 4 = show, 8 = trace
+// system error reporting, sum of: 1 = log; 4 = show
$config['debug_level'] = 1;
// log driver: 'syslog' or 'file'.
diff --git a/installer/config.php b/installer/config.php
index fd7932af4..8b98dbef6 100644
--- a/installer/config.php
+++ b/installer/config.php
@@ -198,9 +198,6 @@ echo '<label for="cfgdebug1">Log errors</label><br />';
echo $check_debug->show(($value & 4) ? 4 : 0, array('value' => 4, 'id' => 'cfgdebug4'));
echo '<label for="cfgdebug4">Print errors (to the browser)</label><br />';
-echo $check_debug->show(($value & 8) ? 8 : 0, array('value' => 8, 'id' => 'cfgdebug8'));
-echo '<label for="cfgdebug8">Verbose display (enables debug console)</label><br />';
-
?>
</dd>
diff --git a/plugins/legacy_browser/js/iehacks.js b/plugins/legacy_browser/js/iehacks.js
new file mode 100644
index 000000000..129ad6003
--- /dev/null
+++ b/plugins/legacy_browser/js/iehacks.js
@@ -0,0 +1,20 @@
+
+// Make getElementById() case-sensitive on IE7
+document._getElementById = document.getElementById;
+document.getElementById = function(id) {
+ var i = 0, obj = document._getElementById(id);
+
+ if (obj && obj.id != id)
+ while ((obj = document.all[i]) && obj.id != id)
+ i++;
+
+ return obj;
+}
+
+// fix missing :last-child selectors
+$(document).ready(function() {
+ if (rcmail && rcmail.env.skin != 'classic')
+ $('ul.treelist ul').each(function(i, ul) {
+ $('li:last-child', ul).css('border-bottom', 0);
+ });
+});
diff --git a/plugins/legacy_browser/legacy_browser.php b/plugins/legacy_browser/legacy_browser.php
index c910d76d4..bdf831e73 100644
--- a/plugins/legacy_browser/legacy_browser.php
+++ b/plugins/legacy_browser/legacy_browser.php
@@ -23,10 +23,12 @@ class legacy_browser extends rcube_plugin
function send_page($args)
{
// replace jQuery 2.x with 1.x
- $ts = filemtime($this->home . '/js/jquery.min.js');
+ $ts1 = filemtime($this->home . '/js/jquery.min.js');
+ $ts2 = filemtime($this->home . '/js/iehacks.js');
$args['content'] = preg_replace(
- '|"program/js/jquery\.min\.js\?s=[0-9]+"|',
- '"plugins/legacy_browser/js/jquery.min.js?s=' . $ts . '"',
+ '|<script src="program/js/jquery\.min\.js\?s=[0-9]+" type="text/javascript"></script>|',
+ '<script src="plugins/legacy_browser/js/jquery.min.js?s=' . $ts1 . '" type="text/javascript"></script>'."\n"
+ .'<script src="plugins/legacy_browser/js/iehacks.js?s=' . $ts2 . '" type="text/javascript"></script>',
$args['content'], 1);
return $args;
@@ -53,17 +55,6 @@ class legacy_browser extends rcube_plugin
'<link rel="stylesheet" type="text/css" href="plugins/legacy_browser/larry/iehacks.css" />'
);
}
-
- // fix missing :last-child selectors
- $rcube->output->add_footer(implode("\n", array(
- '<script type="text/javascript">',
- '$(document).ready(function() {',
- ' $(\'ul.treelist ul\').each(function(i,ul) {',
- ' $(\'li:last-child\', ul).css(\'border-bottom\', 0);',
- ' });',
- '});',
- '</script>'
- )));
}
}
diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php
index a1bcc86ca..4b57f760d 100644
--- a/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php
+++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php
@@ -352,14 +352,13 @@ class rcube_sieve_engine
header("Content-Type: application/octet-stream");
header("Content-Length: ".strlen($script));
- if ($browser->ie)
+ if ($browser->ie) {
header("Content-Type: application/force-download");
- if ($browser->ie && $browser->ver < 7)
- $filename = rawurlencode(abbreviate_string($script_name, 55));
- else if ($browser->ie)
$filename = rawurlencode($script_name);
- else
+ }
+ else {
$filename = addcslashes($script_name, '\\"');
+ }
header("Content-Disposition: attachment; filename=\"$filename.txt\"");
echo $script;
diff --git a/plugins/managesieve/managesieve.js b/plugins/managesieve/managesieve.js
index 46ebc92de..22d57e159 100644
--- a/plugins/managesieve/managesieve.js
+++ b/plugins/managesieve/managesieve.js
@@ -72,22 +72,25 @@ if (window.rcmail) {
if (rcmail.gui_objects.filterslist) {
rcmail.filters_list = new rcube_list_widget(rcmail.gui_objects.filterslist,
{multiselect:false, draggable:true, keyboard:false});
- rcmail.filters_list.addEventListener('select', function(e) { p.managesieve_select(e); });
- rcmail.filters_list.addEventListener('dragstart', function(e) { p.managesieve_dragstart(e); });
- rcmail.filters_list.addEventListener('dragend', function(e) { p.managesieve_dragend(e); });
- rcmail.filters_list.row_init = function (row) {
- row.obj.onmouseover = function() { p.managesieve_focus_filter(row); };
- row.obj.onmouseout = function() { p.managesieve_unfocus_filter(row); };
- };
- rcmail.filters_list.init();
- rcmail.filters_list.focus();
+
+ rcmail.filters_list
+ .addEventListener('select', function(e) { p.managesieve_select(e); })
+ .addEventListener('dragstart', function(e) { p.managesieve_dragstart(e); })
+ .addEventListener('dragend', function(e) { p.managesieve_dragend(e); })
+ .addEventListener('initrow', function(row) {
+ row.obj.onmouseover = function() { p.managesieve_focus_filter(row); };
+ row.obj.onmouseout = function() { p.managesieve_unfocus_filter(row); };
+ })
+ .init().focus();
}
if (rcmail.gui_objects.filtersetslist) {
- rcmail.filtersets_list = new rcube_list_widget(rcmail.gui_objects.filtersetslist, {multiselect:false, draggable:false, keyboard:false});
- rcmail.filtersets_list.addEventListener('select', function(e) { p.managesieve_setselect(e); });
- rcmail.filtersets_list.init();
- rcmail.filtersets_list.focus();
+ rcmail.filtersets_list = new rcube_list_widget(rcmail.gui_objects.filtersetslist,
+ {multiselect:false, draggable:false, keyboard:false});
+
+ rcmail.filtersets_list
+ .addEventListener('select', function(e) { p.managesieve_setselect(e); })
+ .init().focus();
if (set != null) {
set = rcmail.managesieve_setid(set);
diff --git a/plugins/zipdownload/README b/plugins/zipdownload/README
index f253d63ee..e343398c3 100644
--- a/plugins/zipdownload/README
+++ b/plugins/zipdownload/README
@@ -2,8 +2,7 @@ Roundcube Webmail ZipDownload
=============================
This plugin adds an option to download all attachments to a message in one zip
file, when a message has multiple attachments. The plugin also allows the
-download of a selection of messages in 1 zip file and the download of entire
-folders.
+download of a selection of messages in 1 zip file.
Requirements
============
diff --git a/plugins/zipdownload/composer.json b/plugins/zipdownload/composer.json
index 7f6e30935..cdfbf9923 100644
--- a/plugins/zipdownload/composer.json
+++ b/plugins/zipdownload/composer.json
@@ -1,14 +1,19 @@
{
"name": "roundcube/zipdownload",
"type": "roundcube-plugin",
- "description": "Adds an option to download all attachments to a message in one zip file, when a message has multiple attachments. Also allows the download of a selection of messages in one zip file and the download of entire folders.",
+ "description": "Adds an option to download all attachments to a message in one zip file, when a message has multiple attachments. Also allows the download of a selection of messages in one zip file. Supports mbox and maildir format.",
"license": "GNU GPLv3+",
- "version": "2.1",
+ "version": "3.0",
"authors": [
{
"name": "Thomas Bruederli",
"email": "roundcube@gmail.com",
"role": "Lead"
+ },
+ {
+ "name": "Aleksander Machniak",
+ "email": "alec@alec.pl",
+ "role": "Lead"
}
],
"repositories": [
diff --git a/plugins/zipdownload/config.inc.php.dist b/plugins/zipdownload/config.inc.php.dist
index 0b2d14b60..171b4aea5 100644
--- a/plugins/zipdownload/config.inc.php.dist
+++ b/plugins/zipdownload/config.inc.php.dist
@@ -9,9 +9,6 @@
// -1 to prevent downloading of attachments as zip
$config['zipdownload_attachments'] = 1;
-// Zip entire folders
-$config['zipdownload_folder'] = false;
-
// Zip selection of messages
$config['zipdownload_selection'] = false;
diff --git a/plugins/zipdownload/localization/en_US.inc b/plugins/zipdownload/localization/en_US.inc
index aee8a5e15..91145205e 100644
--- a/plugins/zipdownload/localization/en_US.inc
+++ b/plugins/zipdownload/localization/en_US.inc
@@ -5,7 +5,7 @@
| plugins/zipdownload/localization/<lang>.inc |
| |
| Localization file of the Roundcube Webmail Zipdownload plugin |
- | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | Copyright (C) 2012-2014, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -18,6 +18,7 @@
$labels = array();
$labels['downloadall'] = 'Download all attachments';
-$labels['downloadfolder'] = 'Download folder';
-
-?> \ No newline at end of file
+$labels['download'] = 'Download...';
+$labels['downloadmbox'] = 'Mbox format (.zip)';
+$labels['downloadmaildir'] = 'Maildir format (.zip)';
+$labels['downloademl'] = 'Source (.eml)';
diff --git a/plugins/zipdownload/package.xml b/plugins/zipdownload/package.xml
index 3e5722045..7485c5870 100644
--- a/plugins/zipdownload/package.xml
+++ b/plugins/zipdownload/package.xml
@@ -6,7 +6,8 @@
<name>zipdownload</name>
<channel>pear.roundcube.net</channel>
<summary>Download multiple attachments or messages in one zip file</summary>
- <description>Adds an option to download all attachments to a message in one zip file, when a message has multiple attachments. Also allows the download of a selection of messages in one zip file and the download of entire folders.</description>
+ <description>Adds an option to download all attachments to a message in one zip file, when a message has multiple attachments.
+ Also allows the download of a selection of messages in one zip file. Supports mbox and maildir formats.</description>
<lead>
<name>Philip Weir</name>
<user>JohnDoh</user>
@@ -19,11 +20,17 @@
<email>roundcube@gmail.com</email>
<active>yes</active>
</lead>
- <date>2014-04-07</date>
- <time>17:28:00</time>
+ <lead>
+ <name>Aleksander Machniak</name>
+ <user>alec</user>
+ <email>alec@alec.pl</email>
+ <active>yes</active>
+ </lead>
+ <date>2014-04-18</date>
+ <time>09:00:00</time>
<version>
- <release>2.1</release>
- <api>2.0</api>
+ <release>3.0</release>
+ <api>3.0</api>
</version>
<stability>
<release>stable</release>
diff --git a/plugins/zipdownload/zipdownload.js b/plugins/zipdownload/zipdownload.js
index 080dcd9e3..0e0249dd3 100644
--- a/plugins/zipdownload/zipdownload.js
+++ b/plugins/zipdownload/zipdownload.js
@@ -2,32 +2,94 @@
* ZipDownload plugin script
*/
-function rcmail_zipmessages() {
- if (rcmail.message_list && rcmail.message_list.get_selection().length > 1) {
- rcmail.goto_url('plugin.zipdownload.zip_messages', '_mbox=' + urlencode(rcmail.env.mailbox) + '&_uid=' + rcmail.message_list.get_selection().join(','));
- }
+window.rcmail && rcmail.addEventListener('init', function(evt) {
+ // register additional actions
+ rcmail.register_command('download-eml', function() { rcmail_zipdownload('eml'); });
+ rcmail.register_command('download-mbox', function() { rcmail_zipdownload('mbox'); });
+ rcmail.register_command('download-maildir', function() { rcmail_zipdownload('maildir'); });
+
+ // commands status
+ rcmail.message_list.addEventListener('select', function(list) {
+ var selected = list.get_selection().length;
+
+ rcmail.enable_command('download', selected > 0);
+ rcmail.enable_command('download-eml', selected == 1);
+ rcmail.enable_command('download-mbox', 'download-maildir', selected > 1);
+ });
+
+ // hook before default download action
+ rcmail.addEventListener('beforedownload', rcmail_zipdownload_menu);
+
+ // find and modify default download link/button
+ $.each(rcmail.buttons['download'] || [], function() {
+ var link = $('#' + this.id),
+ span = $('span', link);
+
+ if (!span.length) {
+ span = $('<span>');
+ link.html('').append(span);
+ }
+
+ span.addClass('folder-selector-link').text(rcmail.gettext('zipdownload.download'));
+
+ rcmail.env.download_link = link;
+ });
+
+ // hide menu on click out of menu element
+ var fn = function(e) {
+ var menu = $('#zipdownload-menu');
+ if (e.target != menu.get(0))
+ menu.hide();
+ };
+ $(document.body).on('mouseup', fn);
+ $('iframe').contents().on('mouseup', fn)
+ .load(function(e) { try { $(this).contents().on('mouseup', fn); } catch(e) {}; });
+});
+
+
+function rcmail_zipdownload(mode)
+{
+ // default .eml download of single message
+ if (mode == 'eml') {
+ var uid = rcmail.get_single_uid();
+ rcmail.goto_url('viewsource', {_uid: uid, _mbox: rcmail.get_message_mailbox(uid), _save: 1});
+ return;
+ }
+
+ // multi-message download, use hidden form to POST selection
+ if (rcmail.message_list && rcmail.message_list.get_selection().length > 1) {
+ var inputs = [], form = $('#zipdownload-form'),
+ post = rcmail.selection_post_data();
+
+ post._mode = mode;
+ post._token = rcmail.env.request_token;
+
+ $.each(post, function(k, v) {
+ inputs.push($('<input>').attr({type: 'hidden', name: k, value: v}));
+ });
+
+ if (!form.length)
+ form = $('<form>').attr({
+ style: 'display: none',
+ method: 'POST',
+ action: '?_task=mail&_action=plugin.zipdownload.messages'
+ })
+ .appendTo('body');
+
+ form.html('').append(inputs).submit();
+ }
}
-$(document).ready(function() {
- if (window.rcmail) {
- rcmail.addEventListener('init', function(evt) {
- // register command (directly enable in message view mode)
- rcmail.register_command('plugin.zipdownload.zip_folder', function() {
- rcmail.goto_url('plugin.zipdownload.zip_folder', '_mbox=' + urlencode(rcmail.env.mailbox));
- }, rcmail.env.messagecount > 0);
-
- if (rcmail.message_list && rcmail.env.zipdownload_selection) {
- rcmail.message_list.addEventListener('select', function(list) {
- rcmail.enable_command('download', list.get_selection().length > 0);
- });
-
- // check in contextmenu plugin exists and if so allow multiple message download
- if (rcmail.contextmenu_disable_multi)
- rcmail.contextmenu_disable_multi.splice($.inArray('#download', rcmail.contextmenu_disable_multi), 1);
- }
- });
-
- rcmail.addEventListener('listupdate', function(props) { rcmail.enable_command('plugin.zipdownload.zip_folder', rcmail.env.messagecount > 0); } );
- rcmail.addEventListener('beforedownload', function(props) { rcmail_zipmessages(); } );
- }
-}); \ No newline at end of file
+// display download options menu
+function rcmail_zipdownload_menu()
+{
+ // fix menu style and display menu
+ var z_index = rcmail.env.download_link.parents('.popupmenu').css('z-index'),
+ menu = $('#zipdownload-menu').css({'max-height': 'none', 'z-index': z_index + 1}).show();
+
+ // position menu on the screen
+ rcmail.element_position(menu, rcmail.env.download_link);
+
+ // abort default download action
+ return false;
+}
diff --git a/plugins/zipdownload/zipdownload.php b/plugins/zipdownload/zipdownload.php
index 029eecfb8..90a314437 100644
--- a/plugins/zipdownload/zipdownload.php
+++ b/plugins/zipdownload/zipdownload.php
@@ -4,11 +4,13 @@
* ZipDownload
*
* Plugin to allow the download of all message attachments in one zip file
+ * and downloading of many messages in one go.
*
- * @version 2.1
+ * @version 3.0
* @requires php_zip extension (including ZipArchive class)
* @author Philip Weir
* @author Thomas Bruderli
+ * @author Aleksander Machniak
*/
class zipdownload extends rcube_plugin
{
@@ -40,18 +42,11 @@ class zipdownload extends rcube_plugin
$this->add_hook('template_object_messageattachments', array($this, 'attachment_ziplink'));
}
- $this->register_action('plugin.zipdownload.zip_attachments', array($this, 'download_attachments'));
- $this->register_action('plugin.zipdownload.zip_messages', array($this, 'download_selection'));
- $this->register_action('plugin.zipdownload.zip_folder', array($this, 'download_folder'));
+ $this->register_action('plugin.zipdownload.attachments', array($this, 'download_attachments'));
+ $this->register_action('plugin.zipdownload.messages', array($this, 'download_messages'));
- if (($selection = $rcmail->config->get('zipdownload_selection')) || $rcmail->config->get('zipdownload_folder')) {
- $this->include_script('zipdownload.js');
- $this->api->output->set_env('zipdownload_selection', $selection);
-
- if ($rcmail->config->get('zipdownload_folder', false) && ($rcmail->action == '' || $rcmail->action == 'show')) {
- $zipdownload = $this->api->output->button(array('command' => 'plugin.zipdownload.zip_folder', 'type' => 'link', 'classact' => 'active', 'content' => $this->gettext('downloadfolder')));
- $this->api->add_content(html::tag('li', array('class' => 'separator_above'), $zipdownload), 'mailboxoptions');
- }
+ if (!$rcmail->action && $rcmail->config->get('zipdownload_selection')) {
+ $this->download_menu();
}
}
@@ -65,7 +60,7 @@ class zipdownload extends rcube_plugin
// only show the link if there is more than the configured number of attachments
if (substr_count($p['content'], '<li') > $rcmail->config->get('zipdownload_attachments', 1)) {
$href = $rcmail->url(array(
- '_action' => 'plugin.zipdownload.zip_attachments',
+ '_action' => 'plugin.zipdownload.attachments',
'_mbox' => $rcmail->output->env['mailbox'],
'_uid' => $rcmail->output->env['uid'],
));
@@ -92,6 +87,30 @@ class zipdownload extends rcube_plugin
}
/**
+ * Adds download options menu to the page
+ */
+ public function download_menu()
+ {
+ $this->include_script('zipdownload.js');
+ $this->add_label('download');
+
+ $rcmail = rcmail::get_instance();
+ $menu = array();
+ $ul_attr = $rcmail->config->get('skin') == 'classic' ? null : array('class' => 'toolbarmenu');
+
+ foreach (array('eml', 'mbox', 'maildir') as $type) {
+ $menu[] = html::tag('li', null, $rcmail->output->button(array(
+ 'command' => "download-$type",
+ 'label' => "zipdownload.download$type",
+ 'classact' => 'active',
+ )));
+ }
+
+ $rcmail->output->add_footer(html::div(array('id' => 'zipdownload-menu', 'class' => 'popupmenu'),
+ html::tag('ul', $ul_attr, implode('', $menu))));
+ }
+
+ /**
* Handler for attachment download action
*/
public function download_attachments()
@@ -153,52 +172,19 @@ class zipdownload extends rcube_plugin
/**
* Handler for message download action
*/
- public function download_selection()
+ public function download_messages()
{
- if (isset($_REQUEST['_uid'])) {
- $messageset = rcmail::get_uids();
+ $rcmail = rcmail::get_instance();
- if (sizeof($messageset) > 0) {
+ if ($rcmail->config->get('zipdownload_selection') && !empty($_POST['_uid'])) {
+ $messageset = rcmail::get_uids();
+ if (sizeof($messageset)) {
$this->_download_messages($messageset);
}
}
}
/**
- * Handler for folder download action
- */
- public function download_folder()
- {
- @set_time_limit(0);
-
- $imap = rcmail::get_instance()->get_storage();
- $mbox_name = $imap->get_folder();
-
- // initialize searching result if search_filter is used
- if ($_SESSION['search_filter'] && $_SESSION['search_filter'] != 'ALL') {
- $imap->search($mbox_name, $_SESSION['search_filter'], RCUBE_CHARSET);
- }
-
- // fetch message headers for all pages
- $uids = array();
- if ($count = $imap->count($mbox_name, $imap->get_threading() ? 'THREADS' : 'ALL', FALSE)) {
- for ($i = 0; ($i * $imap->get_pagesize()) <= $count; $i++) {
- $a_headers = $imap->list_messages($mbox_name, ($i + 1));
-
- foreach ($a_headers as $header) {
- if (empty($header))
- continue;
-
- array_push($uids, $header->uid);
- }
- }
- }
-
- if (sizeof($uids) > 0)
- $this->_download_messages(array($mbox_name => $uids));
- }
-
- /**
* Helper method to packs all the given messages into a zip archive
*
* @param array List of message UIDs to download
@@ -207,40 +193,80 @@ class zipdownload extends rcube_plugin
{
$rcmail = rcmail::get_instance();
$imap = $rcmail->get_storage();
+ $mode = rcube_utils::get_input_value('_mode', rcube_utils::INPUT_POST);
$temp_dir = $rcmail->config->get('temp_dir');
$tmpfname = tempnam($temp_dir, 'zipdownload');
$tempfiles = array($tmpfname);
$folders = count($messageset) > 1;
+ // @TODO: file size limit
+
// open zip file
$zip = new ZipArchive();
$zip->open($tmpfname, ZIPARCHIVE::OVERWRITE);
- foreach ($messageset as $mbox => $uids){
+ if ($mode == 'mbox') {
+ $tmpfp = fopen($tmpfname . '.mbox', 'w');
+ }
+
+ foreach ($messageset as $mbox => $uids) {
$imap->set_folder($mbox);
$path = $folders ? str_replace($imap->get_hierarchy_delimiter(), '/', $mbox) . '/' : '';
- foreach ($uids as $uid){
+ foreach ($uids as $uid) {
$headers = $imap->get_message_headers($uid);
- $subject = rcube_mime::decode_mime_string((string)$headers->subject);
- $subject = $this->_convert_filename($subject);
- $subject = substr($subject, 0, 16);
-
- $disp_name = ($subject ? $subject : 'message_rfc822') . ".eml";
- $disp_name = $path . $uid . "_" . $disp_name;
- $tmpfn = tempnam($temp_dir, 'zipmessage');
- $tmpfp = fopen($tmpfn, 'w');
- $imap->get_raw_body($uid, $tmpfp);
- $tempfiles[] = $tmpfn;
- fclose($tmpfp);
- $zip->addFile($tmpfn, $disp_name);
+ if ($mode == 'mbox') {
+ $from = rcube_mime::decode_address_list($headers->from, null, true, $headers->charset, true);
+ $from = array_shift($from);
+
+ // Mbox format header
+ // @FIXME: \r\n or \n
+ // @FIXME: date format
+ $header = sprintf("From %s %s\r\n",
+ // replace spaces with hyphens
+ $from ? preg_replace('/\s/', '-', $from) : 'MAILER-DAEMON',
+ // internaldate
+ $headers->internaldate
+ );
+
+ fwrite($tmpfp, $header);
+
+ // Use stream filter to quote "From " in the message body
+ stream_filter_register('mbox_filter', 'zipdownload_mbox_filter');
+ $filter = stream_filter_append($tmpfp, 'mbox_filter');
+ $imap->get_raw_body($uid, $tmpfp);
+ stream_filter_remove($filter);
+ fwrite($tmpfp, "\r\n");
+ }
+ else { // maildir
+ $subject = rcube_mime::decode_mime_string((string)$headers->subject);
+ $subject = $this->_convert_filename($subject);
+ $subject = substr($subject, 0, 16);
+
+ $disp_name = ($subject ? $subject : 'message_rfc822') . ".eml";
+ $disp_name = $path . $uid . "_" . $disp_name;
+
+ $tmpfn = tempnam($temp_dir, 'zipmessage');
+ $tmpfp = fopen($tmpfn, 'w');
+ $imap->get_raw_body($uid, $tmpfp);
+ $tempfiles[] = $tmpfn;
+ fclose($tmpfp);
+ $zip->addFile($tmpfn, $disp_name);
+ }
}
}
+ $filename = $folders ? 'messages' : $imap->get_folder();
+
+ if ($mode == 'mbox') {
+ $tempfiles[] = $tmpfname . '.mbox';
+ fclose($tmpfp);
+ $zip->addFile($tmpfname . '.mbox', $filename . '.mbox');
+ }
+
$zip->close();
- $filename = $folders ? 'messages' : $imap->get_folder();
$this->_deliver_zipfile($tmpfname, $filename . '.zip');
// delete temporary files from disk
@@ -261,9 +287,7 @@ class zipdownload extends rcube_plugin
$rcmail->output->nocacheing_headers();
- if ($browser->ie && $browser->ver < 7)
- $filename = rawurlencode(abbreviate_string($filename, 55));
- else if ($browser->ie)
+ if ($browser->ie)
$filename = rawurlencode($filename);
else
$filename = addcslashes($filename, '"');
@@ -288,6 +312,25 @@ class zipdownload extends rcube_plugin
{
$str = rcube_charset::convert($str, RCUBE_CHARSET, $this->charset);
- return strtr($str, array(':'=>'', '/'=>'-'));
+ return strtr($str, array(':' => '', '/' => '-'));
+ }
+}
+
+class zipdownload_mbox_filter extends php_user_filter
+{
+ function filter($in, $out, &$consumed, $closing)
+ {
+ while ($bucket = stream_bucket_make_writeable($in)) {
+ // messages are read line by line
+ if (preg_match('/^>*From /', $bucket->data)) {
+ $bucket->data = '>' . $bucket->data;
+ $bucket->datalen += 1;
+ }
+
+ $consumed += $bucket->datalen;
+ stream_bucket_append($out, $bucket);
+ }
+
+ return PSFS_PASS_ON;
}
}
diff --git a/program/include/rcmail.php b/program/include/rcmail.php
index 1fd077665..8d7101e85 100644
--- a/program/include/rcmail.php
+++ b/program/include/rcmail.php
@@ -1622,7 +1622,7 @@ class rcmail extends rcube
$count = count($path);
if ($count > 1) {
- for ($i = 0; $i < $count; $i++) {
+ for ($i = 1; $i < $count; $i++) {
$folder = implode($delimiter, array_slice($path, 0, -$i));
if ($folder_class = $this->folder_classname($folder)) {
$name = implode($delimiter, array_slice($path, $count - $i));
diff --git a/program/include/rcmail_output_html.php b/program/include/rcmail_output_html.php
index a23b8405e..c3232b246 100644
--- a/program/include/rcmail_output_html.php
+++ b/program/include/rcmail_output_html.php
@@ -519,25 +519,12 @@ class rcmail_output_html extends rcmail_output
$output = preg_replace_callback('/<form\s+([^>]+)>/Ui', array($this, 'alter_form_tag'), $output);
$this->footer = preg_replace_callback('/<form\s+([^>]+)>/Ui', array($this, 'alter_form_tag'), $this->footer);
- if ($write) {
- // add debug console
- if ($realname != 'error' && ($this->config->get('debug_level') & 8)) {
- $this->add_footer('<div id="console" style="position:absolute;top:5px;left:5px;width:405px;padding:2px;background:white;z-index:9000;display:none">
- <a href="#toggle" onclick="con=$(\'#dbgconsole\');con[con.is(\':visible\')?\'hide\':\'show\']();return false">console</a>
- <textarea name="console" id="dbgconsole" rows="20" cols="40" style="display:none;width:400px;border:none;font-size:10px" spellcheck="false"></textarea></div>'
- );
- $this->add_script(
- "if (!window.console || !window.console.log) {\n".
- " window.console = new rcube_console();\n".
- " $('#console').show();\n".
- "}", 'foot');
- }
- $this->write(trim($output));
- }
- else {
+ if (!$write) {
return $output;
}
+ $this->write(trim($output));
+
if ($exit) {
exit;
}
diff --git a/program/js/app.js b/program/js/app.js
index 2cc14a79e..4a5200028 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -143,7 +143,7 @@ function rcube_webmail()
this.task = this.env.task;
// check browser
- if (!bw.dom || !bw.xmlhttp_test() || (bw.mz && bw.vendver < 1.9) || (bw.ie && bw.vendver < 7)) {
+ if (this.env.server_error != 409 && (!bw.dom || !bw.xmlhttp_test() || (bw.mz && bw.vendver < 1.9) || (bw.ie && bw.vendver < 7))) {
this.goto_url('error', '_code=0x199');
return;
}
@@ -1074,8 +1074,9 @@ function rcube_webmail()
// Reset the auto-save timer
clearTimeout(this.save_timer);
- if (!this.upload_file(props || this.gui_objects.uploadform, 'upload')) {
- alert(this.get_label('selectimportfile'));
+ if (!(flag = this.upload_file(props || this.gui_objects.uploadform, 'upload'))) {
+ if (flag !== false)
+ alert(this.get_label('selectimportfile'));
aborted = true;
}
break;
@@ -1200,12 +1201,15 @@ function rcube_webmail()
break;
case 'import-messages':
- var form = props || this.gui_objects.importform;
- var importlock = this.set_busy(true, 'importwait');
+ var form = props || this.gui_objects.importform,
+ importlock = this.set_busy(true, 'importwait');
+
$('input[name="_unlock"]', form).val(importlock);
- if (!this.upload_file(form, 'import')) {
+
+ if (!(flag = this.upload_file(form, 'import'))) {
this.set_busy(false, null, importlock);
- alert(this.get_label('selectimportfile'));
+ if (flag !== false)
+ alert(this.get_label('selectimportfile'));
aborted = true;
}
break;
@@ -1936,7 +1940,7 @@ function rcube_webmail()
// add each submitted col
for (n in this.env.listcols) {
c = this.env.listcols[n];
- col = { className: String(c).toLowerCase() };
+ col = {className: String(c).toLowerCase(), events:{}};
if (this.env.coltypes[c] && this.env.coltypes[c].hidden) {
col.className += ' hidden';
@@ -1970,11 +1974,8 @@ function rcube_webmail()
else if (c == 'threads')
html = expando;
else if (c == 'subject') {
- if (bw.ie) {
- col.onmouseover = function() { rcube_webmail.long_subject_title_ex(this, message.depth+1); };
- if (bw.ie8)
- tree = '<span></span>' + tree; // #1487821
- }
+ if (bw.ie)
+ col.events.mouseover = function() { rcube_webmail.long_subject_title_ex(this); };
html = tree + cols[c];
}
else if (c == 'priority') {
@@ -4019,7 +4020,7 @@ function rcube_webmail()
this.upload_file = function(form, action)
{
if (!form)
- return false;
+ return;
// count files and size on capable browser
var size = 0, numfiles = 0;
@@ -4079,8 +4080,6 @@ function rcube_webmail()
this.gui_objects.attachmentform = form;
return true;
}
-
- return false;
};
// add file name to attachment list
@@ -4102,7 +4101,7 @@ function rcube_webmail()
li.attr('id', name)
.addClass(att.classname)
.html(att.html)
- .on('mouseover', function() { rcube_webmail.long_subject_title_ex(this, 0); });
+ .on('mouseover', function() { rcube_webmail.long_subject_title_ex(this); });
// replace indicator's li
if (upload_id && (indicator = document.getElementById(upload_id))) {
@@ -6846,7 +6845,7 @@ function rcube_webmail()
param[k] = query[k];
}
- return base + '&' + $.param(param) + querystring;
+ return base + (base.indexOf('?') > -1 ? '&' : '?') + $.param(param) + querystring;
};
this.redirect = function(url, lock)
@@ -7862,7 +7861,7 @@ rcube_webmail.long_subject_title = function(elem, indent)
}
};
-rcube_webmail.long_subject_title_ex = function(elem, indent)
+rcube_webmail.long_subject_title_ex = function(elem)
{
if (!elem.title) {
var $elem = $(elem),
@@ -7874,7 +7873,7 @@ rcube_webmail.long_subject_title_ex = function(elem, indent)
w = tmp.width();
tmp.remove();
- if (w + indent * 15 > $elem.width())
+ if (w + $('span.branch', $elem).width() * 15 > $elem.width())
elem.title = txt;
}
};
diff --git a/program/js/common.js b/program/js/common.js
index ed9488b2c..28f79d56f 100644
--- a/program/js/common.js
+++ b/program/js/common.js
@@ -255,13 +255,17 @@ remove_listener: function(p)
cancel: function(evt)
{
var e = evt ? evt : window.event;
+
if (e.preventDefault)
e.preventDefault();
+ else
+ e.returnValue = false;
+
if (e.stopPropagation)
e.stopPropagation();
e.cancelBubble = true;
- e.returnValue = false;
+
return false;
},
@@ -326,13 +330,17 @@ removeEventListener: function(evt, func, obj)
triggerEvent: function(evt, e)
{
var ret, h;
+
if (e === undefined)
e = this;
else if (typeof e === 'object')
e.event = evt;
- if (this._events && this._events[evt] && !this._event_exec) {
- this._event_exec = true;
+ if (!this._event_exec)
+ this._event_exec = {};
+
+ if (this._events && this._events[evt] && !this._event_exec[evt]) {
+ this._event_exec[evt] = true;
for (var i=0; i < this._events[evt].length; i++) {
if ((h = this._events[evt][i])) {
if (typeof h.func === 'function')
@@ -355,7 +363,8 @@ triggerEvent: function(evt, e)
}
}
- this._event_exec = false;
+ delete this._event_exec[evt];
+
if (e.event) {
try {
delete e.event;
@@ -529,36 +538,6 @@ function getCookie(name)
roundcube_browser.prototype.set_cookie = setCookie;
roundcube_browser.prototype.get_cookie = getCookie;
-// tiny replacement for Firebox functionality
-function rcube_console()
-{
- this.log = function(msg)
- {
- var box = rcube_find_object('dbgconsole');
-
- if (box) {
- if (msg.charAt(msg.length-1)=='\n')
- msg += '--------------------------------------\n';
- else
- msg += '\n--------------------------------------\n';
-
- // Konqueror doesn't allow to just change the value of hidden element
- if (bw.konq) {
- box.innerText += msg;
- box.value = box.innerText;
- } else
- box.value += msg;
- }
- };
-
- this.reset = function()
- {
- var box = rcube_find_object('dbgconsole');
- if (box)
- box.innerText = box.value = '';
- };
-};
-
var bw = new roundcube_browser();
bw.set_html_class();
@@ -596,20 +575,6 @@ if (!String.prototype.startsWith) {
};
}
-// Make getElementById() case-sensitive on IE
-if (bw.ie) {
- document._getElementById = document.getElementById;
- document.getElementById = function(id) {
- var i = 0, obj = document._getElementById(id);
-
- if (obj && obj.id != id)
- while ((obj = document.all[i]) && obj.id != id)
- i++;
-
- return obj;
- }
-}
-
// jQuery plugin to emulate HTML5 placeholder attributes on input elements
jQuery.fn.placeholder = function(text) {
return this.each(function() {
diff --git a/program/js/list.js b/program/js/list.js
index 9b7779c7b..a39bb5abe 100644
--- a/program/js/list.js
+++ b/program/js/list.js
@@ -301,11 +301,13 @@ insert_row: function(row, before)
if (row.style) $.extend(domrow.style, row.style);
if (row.uid) $(domrow).data('uid', row.uid);
- for (var domcell, col, i=0; row.cols && i < row.cols.length; i++) {
+ for (var e, domcell, col, i=0; row.cols && i < row.cols.length; i++) {
col = row.cols[i];
domcell = document.createElement(this.col_tagname());
if (col.className) domcell.className = col.className;
if (col.innerHTML) domcell.innerHTML = col.innerHTML;
+ for (e in col.events)
+ domcell['on' + e] = col.events[e];
domrow.appendChild(domcell);
}
diff --git a/program/lib/Roundcube/rcube_csv2vcard.php b/program/lib/Roundcube/rcube_csv2vcard.php
index aa385dce4..06bc387d5 100644
--- a/program/lib/Roundcube/rcube_csv2vcard.php
+++ b/program/lib/Roundcube/rcube_csv2vcard.php
@@ -56,7 +56,7 @@ class rcube_csv2vcard
//'email_2_type' => '',
//'email_3_address' => '', //@TODO
//'email_3_type' => '',
- 'email_address' => 'email:main',
+ 'email_address' => 'email:pref',
//'email_type' => '',
'first_name' => 'firstname',
'gender' => 'gender',
diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php
index 5c30327a1..baca052b8 100644
--- a/program/lib/Roundcube/rcube_imap.php
+++ b/program/lib/Roundcube/rcube_imap.php
@@ -1544,20 +1544,27 @@ class rcube_imap extends rcube_storage
*/
public function search_once($folder = null, $str = 'ALL')
{
+ if (!$this->check_connection()) {
+ return new rcube_result_index();
+ }
+
if (!$str) {
$str = 'ALL';
}
- if (!strlen($folder)) {
- $folder = $this->folder;
+ // multi-folder search
+ if (is_array($folder) && count($folder) > 1) {
+ $searcher = new rcube_imap_search($this->options, $this->conn);
+ $index = $searcher->exec($folder, $str, $this->default_charset);
}
-
- if (!$this->check_connection()) {
- return new rcube_result_index();
+ else {
+ $folder = is_array($folder) ? $folder[0] : $folder;
+ if (!strlen($folder)) {
+ $folder = $this->folder;
+ }
+ $index = $this->conn->search($folder, $str, true);
}
- $index = $this->conn->search($folder, $str, true);
-
return $index;
}
@@ -1707,15 +1714,15 @@ class rcube_imap extends rcube_storage
*/
public function get_message_headers($uid, $folder = null, $force = false)
{
- if (!strlen($folder)) {
- $folder = $this->folder;
- }
-
// decode combined UID-folder identifier
if (preg_match('/^\d+-.+/', $uid)) {
list($uid, $folder) = explode('-', $uid, 2);
}
+ if (!strlen($folder)) {
+ $folder = $this->folder;
+ }
+
// get cached headers
if (!$force && $uid && ($mcache = $this->get_mcache_engine())) {
$headers = $mcache->get_message($folder, $uid);
@@ -1726,6 +1733,9 @@ class rcube_imap extends rcube_storage
else {
$headers = $this->conn->fetchHeader(
$folder, $uid, true, true, $this->get_fetch_headers());
+
+ if (is_object($headers))
+ $headers->folder = $folder;
}
return $headers;
diff --git a/program/steps/mail/get.inc b/program/steps/mail/get.inc
index 8f869c67c..c6262097f 100644
--- a/program/steps/mail/get.inc
+++ b/program/steps/mail/get.inc
@@ -293,9 +293,7 @@ else if (strlen($part_id)) {
$filename = rcmail_attachment_name($part);
- if ($browser->ie && $browser->ver < 7)
- $filename = rawurlencode(abbreviate_string($filename, 55));
- else if ($browser->ie)
+ if ($browser->ie)
$filename = rawurlencode($filename);
else
$filename = addcslashes($filename, '"');
diff --git a/program/steps/mail/import.inc b/program/steps/mail/import.inc
index 217927537..ef78ad945 100644
--- a/program/steps/mail/import.inc
+++ b/program/steps/mail/import.inc
@@ -5,7 +5,7 @@
| program/steps/mail/import.inc |
| |
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2005-2013, The Roundcube Dev Team |
+ | Copyright (C) 2005-2014, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@@ -16,6 +16,7 @@
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+ | Author: Aleksander Machniak <alec@alec.pl> |
+-----------------------------------------------------------------------+
*/
@@ -31,46 +32,62 @@ if (is_array($_FILES['_file'])) {
if (!$err) {
// check file content type first
- list($mtype_primary,) = explode('/', rcube_mime::file_content_type($filepath, $_FILES['_file']['name'][$i], $_FILES['_file']['type'][$i]));
+ $ctype = rcube_mime::file_content_type($filepath, $_FILES['_file']['name'][$i], $_FILES['_file']['type'][$i]);
+ list($mtype_primary, $mtype_secondary) = explode('/', $ctype);
- if (!in_array($mtype_primary, array('text','message'))) {
+ if (in_array($ctype, array('application/zip', 'application/x-zip'))) {
+ $filepath = rcmail_zip_extract($filepath);
+ if (empty($filepath)) {
+ continue;
+ }
+ }
+ else if (!in_array($mtype_primary, array('text', 'message'))) {
continue;
}
- // read the first few lines to detect header-like structure
- $fp = fopen($filepath, 'r');
- do {
- $line = fgets($fp);
- }
- while ($line !== false && trim($line) == '');
+ foreach ((array) $filepath as $file) {
+ // read the first few lines to detect header-like structure
+ $fp = fopen($file, 'r');
+ do {
+ $line = fgets($fp);
+ }
+ while ($line !== false && trim($line) == '');
- if (!preg_match('/^From\s+-/', $line) && !preg_match('/^[a-z-_]+:\s+.+/i', $line)) {
- continue;
- }
+ if (!preg_match('/^From .+/', $line) && !preg_match('/^[a-z-_]+:\s+.+/i', $line)) {
+ continue;
+ }
- $message = $lastline = '';
- fseek($fp, 0);
- while (($line = fgets($fp)) !== false) {
- // importing mbox file, split by From - lines
- if (preg_match('/^From\s+-/', $line) && ($lastline == '' || substr($lastline, -2) == '--')) {
- if (!empty($message)) {
- if ($RCMAIL->storage->save_message(null, rtrim($message))) {
- $imported++;
- }
- else {
- rcube::raise_error("Failed to import message to " . $RCMAIL->storage->get_folder(), false, true);
+ $message = $lastline = '';
+ fseek($fp, 0);
+ while (($line = fgets($fp)) !== false) {
+ // importing mbox file, split by From - lines
+ if ($lastline === '' && strncmp($line, 'From ', 5) === 0 && strlen($line) > 5) {
+ if (!empty($message)) {
+ // unquote ">From " lines in message body
+ $message = preg_replace('/\n>([>]*)From /', "\n\\1From ", $message);
+ if ($RCMAIL->storage->save_message(null, rtrim($message))) {
+ $imported++;
+ }
+ else {
+ rcube::raise_error("Failed to import message to " . $RCMAIL->storage->get_folder(), false, true);
+ }
+ $message = '';
}
- $message = '';
+ continue;
}
- continue;
+
+ $message .= $line;
+ $lastline = rtrim($line);
}
- $message .= $line;
- $lastline = rtrim($line);
- }
+ if (!empty($message) && $RCMAIL->storage->save_message(null, rtrim($message))) {
+ $imported++;
+ }
- if (!empty($message) && $RCMAIL->storage->save_message(null, rtrim($message))) {
- $imported++;
+ // remove temp files extracted from zip
+ if (is_array($filepath)) {
+ unlink($file);
+ }
}
}
@@ -104,3 +121,39 @@ else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// send html page with JS calls as response
$OUTPUT->send('iframe');
+
+
+function rcmail_zip_extract($path)
+{
+ if (!class_exists('ZipArchive', false)) {
+ return;
+ }
+
+ $rcmail = rcmail::get_instance();
+ $temp_dir = $rcmail->config->get('temp_dir');
+ $zip = new ZipArchive;
+ $files = array();
+
+ if ($zip->open($path)) {
+ for ($i = 0; $i < $zip->numFiles; $i++) {
+ $entry = $zip->getNameIndex($i);
+ $tmpfname = tempnam($temp_dir, 'zipimport');
+
+ if (copy("zip://$path#$entry", $tmpfname)) {
+ $ctype = rcube_mime::file_content_type($tmpfname, $entry);
+ list($mtype_primary, $mtype_secondary) = explode('/', $ctype);
+
+ if (in_array($mtype_primary, array('text', 'message'))) {
+ $files[] = $tmpfname;
+ }
+ else {
+ unlink($tmpfname);
+ }
+ }
+ }
+
+ $zip->close();
+ }
+
+ return $files;
+}
diff --git a/program/steps/mail/viewsource.inc b/program/steps/mail/viewsource.inc
index 0328d9600..f988f679a 100644
--- a/program/steps/mail/viewsource.inc
+++ b/program/steps/mail/viewsource.inc
@@ -33,9 +33,7 @@ if ($uid = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_GET)) {
$filename = ($subject ? $subject : $RCMAIL->config->get('product_name', 'email')) . '.eml';
$browser = $RCMAIL->output->browser;
- if ($browser->ie && $browser->ver < 7)
- $filename = rawurlencode(abbreviate_string($filename, 55));
- else if ($browser->ie)
+ if ($browser->ie)
$filename = rawurlencode($filename);
else
$filename = addcslashes($filename, '"');
diff --git a/program/steps/settings/func.inc b/program/steps/settings/func.inc
index 47efa5a70..bccd9caa8 100644
--- a/program/steps/settings/func.inc
+++ b/program/steps/settings/func.inc
@@ -346,6 +346,7 @@ function rcmail_user_prefs($current = null)
$license_link = $meta['license-url'] ? html::a(array('href' => $meta['license-url'], 'target' => '_blank'), rcube::Q($meta['license'])) : rcube::Q($meta['license']);
}
+ $skinnames[] = mb_strtolower($skinname);
$blocks['skin']['options'][$skin]['content'] = html::label(array('class' => 'skinselection'),
html::span('skinitem', $input->show($config['skin'], array('value' => $skin, 'id' => $field_id.$skin))) .
html::span('skinitem', html::img(array('src' => $thumbnail, 'class' => 'skinthumbnail', 'alt' => $skin, 'width' => 64, 'height' => 64))) .
@@ -354,6 +355,7 @@ function rcmail_user_prefs($current = null)
html::span('skinlicense', $license_link ? $RCMAIL->gettext('license').':&nbsp;' . $license_link : ''))
);
}
+ array_multisort($blocks['skin']['options'], SORT_ASC, SORT_STRING, $skinnames);
}
}
diff --git a/skins/classic/common.css b/skins/classic/common.css
index 30370205a..4367d26cb 100644
--- a/skins/classic/common.css
+++ b/skins/classic/common.css
@@ -941,11 +941,6 @@ a.rcmContactAddress:hover
font-weight: bold;
}
-#console
-{
- opacity: 0.8;
-}
-
.disabled,
a.disabled
{