From 3412e50b54e3daac8745234e21ab6e72be0ed165 Mon Sep 17 00:00:00 2001 From: Thomas Bruederli <thomas@roundcube.net> Date: Wed, 04 Jun 2014 11:20:33 -0400 Subject: [PATCH] Fix attachment menu structure and aria-attributes --- program/steps/mail/func.inc | 206 ++++++++++++++++++++++++++++++++++----------------- 1 files changed, 136 insertions(+), 70 deletions(-) diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc index 45d4242..d8211f5 100644 --- a/program/steps/mail/func.inc +++ b/program/steps/mail/func.inc @@ -5,7 +5,7 @@ | program/steps/mail/func.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. | @@ -24,20 +24,19 @@ $RCMAIL->storage_init(); // set imap properties and session vars -if (strlen(trim($mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_GPC, true)))) { - $RCMAIL->storage->set_folder(($_SESSION['mbox'] = $mbox)); +if (!strlen($mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_GPC, true))) { + $mbox = strlen($_SESSION['mbox']) ? $_SESSION['mbox'] : 'INBOX'; } -else if ($RCMAIL->storage) { - $_SESSION['mbox'] = $RCMAIL->storage->get_folder(); +if (!($page = intval($_GET['_page']))) { + $page = $_SESSION['page'] ? $_SESSION['page'] : 1; } -if (!empty($_GET['_page'])) { - $RCMAIL->storage->set_page(($_SESSION['page'] = intval($_GET['_page']))); -} +$RCMAIL->storage->set_folder($_SESSION['mbox'] = $mbox); +$RCMAIL->storage->set_page($_SESSION['page'] = $page); $a_threading = $RCMAIL->config->get('message_threading', array()); $message_sort_col = $RCMAIL->config->get('message_sort_col'); -$message_sort_order = $RCMAIL->config->get('message_sort_col'); +$message_sort_order = $RCMAIL->config->get('message_sort_order'); // set default sort col/order to session if (!isset($_SESSION['sort_col'])) { @@ -69,8 +68,8 @@ } // remove mbox part from _uid -if (($_uid = get_input_value('_uid', RCUBE_INPUT_GPC)) && preg_match('/^\d+-[^,]+$/', $_uid)) { - list($_uid, $mbox) = explode('-', $_uid); +if (($_uid = rcube_utils::get_input_value('_uid', RCUBE_INPUT_GPC)) && !is_array($_uid) && preg_match('/^\d+-.+/', $_uid)) { + list($_uid, $mbox) = explode('-', $_uid, 2); if (isset($_GET['_uid'])) $_GET['_uid'] = $_uid; if (isset($_POST['_uid'])) $_POST['_uid'] = $_uid; $_REQUEST['_uid'] = $_uid; @@ -84,6 +83,9 @@ } } +if (!empty($_SESSION['browser_caps']) && !$OUTPUT->ajax_call) { + $OUTPUT->set_env('browser_capabilities', $_SESSION['browser_caps']); +} // set main env variables, labels and page title if (empty($RCMAIL->action) || $RCMAIL->action == 'list') { @@ -105,6 +107,9 @@ } $OUTPUT->set_env('search_mods', rcmail_search_mods()); + + if (!empty($_SESSION['search_scope'])) + $OUTPUT->set_env('search_scope', $_SESSION['search_scope']); } $threading = (bool) $RCMAIL->storage->get_threading(); @@ -134,17 +139,15 @@ $RCMAIL->set_env_config(array('delete_junk', 'flag_for_deletion', 'read_when_deleted', 'skip_deleted', 'display_next', 'message_extwin', 'compose_extwin', 'forward_attachment')); - if (!empty($_SESSION['browser_caps'])) { - $OUTPUT->set_env('browser_capabilities', $_SESSION['browser_caps']); - } - if (!$OUTPUT->ajax_call) { $OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash', 'movingmessage', 'copyingmessage', 'deletingmessage', 'markingmessage', - 'copy', 'move', 'quota', 'replyall', 'replylist', 'importwait'); + 'copy', 'move', 'quota', 'replyall', 'replylist', 'stillsearching', + 'flagged', 'unflagged', 'unread', 'deleted', 'replied', 'forwarded', + 'priority', 'withattachment'); } - $pagetitle = $RCMAIL->localize_foldername($RCMAIL->storage->mod_folder($mbox_name), true); + $pagetitle = $RCMAIL->localize_foldername($mbox_name, true); $pagetitle = str_replace($delimiter, " \xC2\xBB ", $pagetitle); $OUTPUT->set_pagetitle($pagetitle); @@ -182,35 +185,6 @@ 'group-expand' => 'autocomplete.inc', )); - -/** - * Returns message UID(s) and IMAP folder(s) from GET/POST data - * - * @return array List of message UIDs per folder - */ -function rcmail_get_uids() -{ - // message UID (or comma-separated list of IDs) is provided in - // the form of <ID>-<MBOX>[,<ID>-<MBOX>]* - - $_uid = get_input_value('_uid', RCUBE_INPUT_GPC); - $_mbox = (string)get_input_value('_mbox', RCUBE_INPUT_GPC); - - if (is_array($uid)) { - return $uid; - } - - // create a per-folder UIDs array - $result = array(); - foreach (explode(',', $_uid) as $uid) { - list($uid, $mbox) = explode('-', $uid, 2); - if (empty($mbox)) - $mbox = $_mbox; - $result[$mbox][] = $uid; - } - - return $result; -} /** * Returns default search mods @@ -343,7 +317,7 @@ $OUTPUT->set_env('sort_col', $_SESSION['sort_col']); $OUTPUT->set_env('sort_order', $_SESSION['sort_order']); $OUTPUT->set_env('messages', array()); - $OUTPUT->set_env('coltypes', $a_show_cols); + $OUTPUT->set_env('listcols', $a_show_cols); $OUTPUT->include_script('list.js'); @@ -360,7 +334,7 @@ /** * return javascript commands to add rows to the message list */ -function rcmail_js_message_list($a_headers, $insert_top=FALSE, $a_show_cols=null) +function rcmail_js_message_list($a_headers, $insert_top=false, $a_show_cols=null) { global $RCMAIL, $OUTPUT; @@ -379,6 +353,14 @@ $head_replace = true; } + // add 'folder' column to list on multi-folder searches + $search_set = $RCMAIL->storage->get_search_set(); + $multifolder = $search_set && $search_set[1]->multi; + if ($multifolder && !in_array('folder', $a_show_cols)) { + $a_show_cols[] = 'folder'; + $head_replace = true; + } + $mbox = $RCMAIL->storage->get_folder(); // make sure 'threads' and 'subject' columns are present @@ -386,8 +368,6 @@ array_unshift($a_show_cols, 'subject'); if (!in_array('threads', $a_show_cols)) array_unshift($a_show_cols, 'threads'); - - $_SESSION['list_attrib']['columns'] = $a_show_cols; // Make sure there are no duplicated columns (#1486999) $a_show_cols = array_unique($a_show_cols); @@ -409,6 +389,12 @@ $OUTPUT->command('set_message_coltypes', $a_show_cols, $thead, $smart_col); + if ($multifolder && $_SESSION['search_scope'] == 'all') { + $OUTPUT->command('select_folder', ''); + } + + $OUTPUT->set_env('multifolder_listing', $multifolder); + if (empty($a_headers)) { return; } @@ -424,6 +410,14 @@ foreach ($a_headers as $header) { if (empty($header)) continue; + + // make message UIDs unique by appending the folder name + if ($multifolder) { + $header->uid .= '-'.$header->folder; + $header->flags['skip_mbox_check'] = true; + if ($header->parent_uid) + $header->parent_uid .= '-'.$header->folder; + } $a_msg_cols = array(); $a_msg_flags = array(); @@ -515,20 +509,25 @@ $a_sort_cols = array('subject', 'date', 'from', 'to', 'fromto', 'size', 'cc'); if (!empty($attrib['optionsmenuicon'])) { - $onclick = 'return ' . rcmail_output::JS_OBJECT_NAME . ".command('menu-open', 'messagelistmenu')"; - if ($attrib['optionsmenuicon'] === true || $attrib['optionsmenuicon'] == 'true') - $list_menu = html::div(array('onclick' => $onclick, 'class' => 'listmenu', - 'id' => 'listmenulink', 'title' => $RCMAIL->gettext('listoptions'))); - else - $list_menu = html::a(array('href' => '#', 'onclick' => $onclick), - html::img(array('src' => $skin_path . $attrib['optionsmenuicon'], - 'id' => 'listmenulink', 'title' => $RCMAIL->gettext('listoptions')))); + $onclick = 'return ' . rcmail_output::JS_OBJECT_NAME . ".command('menu-open', 'messagelistmenu', this, event)"; + $inner = $RCMAIL->gettext('listoptions'); + if (is_string($attrib['optionsmenuicon']) && $attrib['optionsmenuicon'] != 'true') { + $inner = html::img(array('src' => $skin_path . $attrib['optionsmenuicon'], 'alt' => $RCMAIL->gettext('listoptions'))); + } + $list_menu = html::a(array( + 'href' => '#list-options', + 'onclick' => $onclick, + 'class' => 'listmenu', + 'id' => 'listmenulink', + 'title' => $RCMAIL->gettext('listoptions'), + 'tabindex' => '0', + ), $inner); } else { $list_menu = ''; } - $cells = array(); + $cells = $coltypes = array(); // get name of smart From/To column in folder context if (array_search('fromto', $a_show_cols) !== false) { @@ -536,32 +535,41 @@ } foreach ($a_show_cols as $col) { + $label = ''; + $sortable = false; + // get column name switch ($col) { case 'flag': - $col_name = '<span class="flagged"> </span>'; + $col_name = html::span('flagged', $RCMAIL->gettext('flagged')); break; case 'attachment': case 'priority': + $col_name = html::span($col, $RCMAIL->gettext($col)); + break; case 'status': - $col_name = '<span class="' . $col .'"> </span>'; + $col_name = html::span($col, $RCMAIL->gettext('readstatus')); break; case 'threads': $col_name = $list_menu; break; case 'fromto': - $col_name = rcube::Q($RCMAIL->gettext($smart_col)); + $label = $RCMAIL->gettext($smart_col); + $col_name = rcube::Q($label); break; default: - $col_name = rcube::Q($RCMAIL->gettext($col)); + $label = $RCMAIL->gettext($col); + $col_name = rcube::Q($label); } // make sort links if (in_array($col, $a_sort_cols)) { + $sortable = true; $col_name = html::a(array( - 'href' => "./#sort", - 'onclick' => 'return '.rcmail_output::JS_OBJECT_NAME.".command('sort','".$col."',this)", - 'title' => $RCMAIL->gettext('sortby') + 'href' => "./#sort", + 'class' => 'sortcol', + 'rel' => $col, + 'title' => $RCMAIL->gettext('sortby') ), $col_name); } else if ($col_name[0] != '<') { @@ -573,8 +581,10 @@ // put it all together $cells[] = array('className' => $class_name, 'id' => "rcm$col", 'html' => $col_name); + $coltypes[$col] = array('className' => $class_name, 'id' => "rcm$col", 'label' => $label, 'sortable' => $sortable); } + $RCMAIL->output->set_env('coltypes', $coltypes); return $cells; } @@ -630,7 +640,7 @@ $max = $RCMAIL->storage->count(NULL, $RCMAIL->storage->get_threading() ? 'THREADS' : 'ALL'); if ($max == 0) - $out = $RCMAIL->gettext('mailboxempty'); + $out = $RCMAIL->storage->get_search_set() ? $RCMAIL->gettext('nomessages') : $RCMAIL->gettext('mailboxempty'); else $out = $RCMAIL->gettext(array('name' => $RCMAIL->storage->get_threading() ? 'threadsfromto' : 'messagesfromto', 'vars' => array('from' => $start_msg, @@ -1740,7 +1750,8 @@ { $parts = array(); foreach ($p as $key => $val) { - $parts[] = $key . '=' . ($key == 'folder' ? base64_encode($val) : $val); + $encode = $key == 'folder' || strpos($val, ';') !== false; + $parts[] = $key . '=' . ($encode ? 'B::' . base64_encode($val) : $val); } return join('; ', $parts); @@ -1752,7 +1763,10 @@ foreach (preg_split('/;\s+/', $str) as $part) { list($key, $val) = explode('=', $part, 2); - if ($key == 'folder') { + if (strpos($val, 'B::') === 0) { + $val = base64_decode(substr($val, 3)); + } + else if ($key == 'folder') { $val = base64_decode($val); } @@ -2031,7 +2045,7 @@ $ctypes = array('application/', 'multipart/m', 'multipart/signed', 'multipart/report'); // Build search string of "with attachment" filter - $attachment = str_repeat(' OR', count($ctypes)-1); + $attachment = trim(str_repeat(' OR', count($ctypes)-1)); foreach ($ctypes as $type) { $attachment .= ' HEADER Content-Type ' . rcube_imap_generic::escape($type); } @@ -2117,6 +2131,58 @@ $content); $RCMAIL->output->add_gui_object('importform', $attrib['id'].'Frm'); + $RCMAIL->output->add_label('selectimportfile','importwait'); return html::div($attrib, $out); } + +/** + * Add groups from the given address source to the address book widget + */ +function rcmail_compose_contact_groups($abook, $source_id, $search = null, $search_mode = 0) +{ + global $RCMAIL, $OUTPUT; + + $jsresult = array(); + foreach ($abook->list_groups($search, $search_mode) as $group) { + $abook->reset(); + $abook->set_group($group['ID']); + $group_prop = $abook->get_group($group['ID']); + + // group (distribution list) with email address(es) + if ($group_prop['email']) { + foreach ((array)$group_prop['email'] as $email) { + $row_id = 'G'.$group['ID']; + $jsresult[$row_id] = format_email_recipient($email, $group['name']); + $OUTPUT->command('add_contact_row', $row_id, array( + 'contactgroup' => html::span(array('title' => $email), rcube::Q($group['name']))), 'group'); + } + } + // make virtual groups clickable to list their members + else if ($group_prop['virtual']) { + $row_id = 'G'.$group['ID']; + $OUTPUT->command('add_contact_row', $row_id, array( + 'contactgroup' => html::a(array( + 'href' => '#list', + 'rel' => $group['ID'], + 'title' => $RCMAIL->gettext('listgroup'), + 'onclick' => sprintf("return %s.command('pushgroup',{'source':'%s','id':'%s'},this,event)", + rcmail_output::JS_OBJECT_NAME, $source_id, $group['ID']), + ), rcube::Q($group['name']) . ' ' . html::span('action', '»'))), + 'group', + array('ID' => $group['ID'], 'name' => $group['name'], 'virtual' => true)); + } + // show group with count + else if (($result = $abook->count()) && $result->count) { + $row_id = 'E'.$group['ID']; + $jsresult[$row_id] = $group['name']; + $OUTPUT->command('add_contact_row', $row_id, array( + 'contactgroup' => rcube::Q($group['name'] . ' (' . intval($result->count) . ')')), 'group'); + } + } + + $abook->reset(); + $abook->set_group(0); + + return $jsresult; +} -- Gitblit v1.9.1