diff options
Diffstat (limited to 'program')
-rw-r--r-- | program/include/rcmail.php | 2 | ||||
-rw-r--r-- | program/include/rcmail_output_html.php | 19 | ||||
-rw-r--r-- | program/js/app.js | 39 | ||||
-rw-r--r-- | program/js/common.js | 61 | ||||
-rw-r--r-- | program/js/list.js | 4 | ||||
-rw-r--r-- | program/lib/Roundcube/rcube_csv2vcard.php | 2 | ||||
-rw-r--r-- | program/lib/Roundcube/rcube_imap.php | 32 | ||||
-rw-r--r-- | program/steps/mail/get.inc | 4 | ||||
-rw-r--r-- | program/steps/mail/import.inc | 113 | ||||
-rw-r--r-- | program/steps/mail/viewsource.inc | 4 | ||||
-rw-r--r-- | program/steps/settings/func.inc | 2 |
11 files changed, 148 insertions, 134 deletions
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').': ' . $license_link : '')) ); } + array_multisort($blocks['skin']['options'], SORT_ASC, SORT_STRING, $skinnames); } } |