summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Bruederli <thomas@roundcube.net>2014-06-02 16:35:12 +0200
committerThomas Bruederli <thomas@roundcube.net>2014-06-02 16:35:12 +0200
commitd58c39126f6e1754e29b6f3bbc01f0f6a3ea2581 (patch)
treee5a6313654f1475a2d83d60a6d3c03c667c5035b
parent22a2c5e0eefcea8572f2ab5ad2e5a22789b6f555 (diff)
Some more improvemements on content structure, text representation and keyboard navigation within the mail view
-rw-r--r--program/include/rcmail.php2
-rw-r--r--program/include/rcmail_output_html.php4
-rw-r--r--program/js/app.js35
-rw-r--r--program/js/list.js3
-rw-r--r--program/localization/en_US/labels.inc3
-rw-r--r--program/steps/mail/list_contacts.inc2
-rw-r--r--program/steps/mail/search_contacts.inc2
-rw-r--r--skins/classic/mail.css1
-rw-r--r--skins/larry/styles.css6
-rw-r--r--skins/larry/templates/compose.html10
-rw-r--r--skins/larry/templates/mail.html1
-rw-r--r--skins/larry/templates/messagepart.html4
-rw-r--r--skins/larry/templates/messagepreview.html4
13 files changed, 54 insertions, 23 deletions
diff --git a/program/include/rcmail.php b/program/include/rcmail.php
index cc70739cf..8e66e85e7 100644
--- a/program/include/rcmail.php
+++ b/program/include/rcmail.php
@@ -1501,7 +1501,7 @@ class rcmail extends rcube
$html_name = $this->Q($foldername) . ($unread ? html::span('unreadcount', sprintf($attrib['unreadwrap'], $unread)) : '');
$link_attrib = $folder['virtual'] ? array() : array(
'href' => $this->url(array('_mbox' => $folder['id'])),
- 'onclick' => sprintf("return %s.command('list','%s',this)", rcmail_output::JS_OBJECT_NAME, $js_name),
+ 'onclick' => sprintf("return %s.command('list','%s',this,event)", rcmail_output::JS_OBJECT_NAME, $js_name),
'rel' => $folder['id'],
'title' => $title,
);
diff --git a/program/include/rcmail_output_html.php b/program/include/rcmail_output_html.php
index 1fa0376fb..e8b5c9828 100644
--- a/program/include/rcmail_output_html.php
+++ b/program/include/rcmail_output_html.php
@@ -859,10 +859,10 @@ EOF;
}
// localize title and summary attributes
- if (!empty($attrib['title']) && $this->app->text_exists($attrib['title'])) {
+ if ($command != 'button' && !empty($attrib['title']) && $this->app->text_exists($attrib['title'])) {
$attrib['title'] = $this->app->gettext($attrib['title']);
}
- if (!empty($attrib['summary']) && $this->app->text_exists($attrib['summary'])) {
+ if ($command != 'button' && !empty($attrib['summary']) && $this->app->text_exists($attrib['summary'])) {
$attrib['summary'] = $this->app->gettext($attrib['summary']);
}
diff --git a/program/js/app.js b/program/js/app.js
index bf163c614..e7f9d02b6 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -342,7 +342,16 @@ function rcube_webmail()
.addEventListener('initrow', function(o) { ref.triggerEvent('insertrow', { cid:o.uid, row:o }); })
.addEventListener('select', function(o) { ref.compose_recipient_select(o); })
.addEventListener('dblclick', function(o) { ref.compose_add_recipient('to'); })
- .addEventListener('keypress', function(o) { if (o.key_pressed == o.ENTER_KEY) ref.compose_add_recipient('to'); })
+ .addEventListener('keypress', function(o) {
+ if (o.key_pressed == o.ENTER_KEY) {
+ if (!ref.compose_add_recipient('to')) {
+ // execute link action on <enter> if not a recipient entry
+ if (o.last_selected && String(o.last_selected).charAt(0) == 'G') {
+ $(o.rows[o.last_selected].obj).find('a').first().click();
+ }
+ }
+ }
+ })
.init();
}
@@ -602,7 +611,7 @@ function rcube_webmail()
{
var ret, uid, cid, url, flag, aborted = false;
- if (obj && obj.blur)
+ if (obj && obj.blur && !(event || rcube_event.is_keyboard(event)))
obj.blur();
// do nothing if interface is locked by other command (with exception for searching reset)
@@ -1647,9 +1656,12 @@ function rcube_webmail()
{
// Helper method to move focus to the next/prev active menu item
var focus_menu_item = function(dir) {
- var obj, mod = dir < 0 ? 'prevAll' : 'nextAll', limit = dir < 0 ? 'last' : 'first';
+ var obj, item, mod = dir < 0 ? 'prevAll' : 'nextAll', limit = dir < 0 ? 'last' : 'first';
if (ref.focused_menu && (obj = $('#'+ref.focused_menu))) {
- return obj.find(':focus').closest('li')[mod](':has(:not([aria-disabled=true]))').find('a,input')[limit]().focus().length;
+ item = obj.find(':focus').closest('li')[mod](':has(:not([aria-disabled=true]))').find('a,input')[limit]();
+ if (!item.length)
+ item = obj.find(':focus').closest('ul')[mod](':has(:not([aria-disabled=true]))').find('a,input')[limit]();
+ return item.focus().length;
}
return 0;
@@ -2402,7 +2414,6 @@ function rcube_webmail()
this.clear_message_list = function()
{
this.env.messages = {};
- this.last_selected = 0;
this.show_contentframe(false);
if (this.message_list)
@@ -3490,6 +3501,8 @@ function rcube_webmail()
input.val(oldval + recipients.join(delim + ' ') + delim + ' ');
this.triggerEvent('add-recipient', { field:field, recipients:recipients });
}
+
+ return recipients.length;
};
// checks the input fields before sending a message
@@ -7405,7 +7418,8 @@ function rcube_webmail()
this.enable_command('set-listmode', this.env.threads && !is_multifolder);
if ((response.action == 'list' || response.action == 'search') && this.message_list) {
- this.message_list.focus();
+ if (this.message_list.rowcount > 0)
+ this.message_list.focus();
this.msglist_select(this.message_list);
this.triggerEvent('listupdate', { folder:this.env.mailbox, rowcount:this.message_list.rowcount });
}
@@ -7417,11 +7431,18 @@ function rcube_webmail()
this.enable_command('search-create', this.env.source == '');
this.enable_command('search-delete', this.env.search_id);
this.update_group_commands();
- this.contact_list.focus();
+ if (this.contact_list.rowcount > 0)
+ this.contact_list.focus();
this.triggerEvent('listupdate', { folder:this.env.source, rowcount:this.contact_list.rowcount });
}
}
break;
+
+ case 'list-contacts':
+ case 'search-contacts':
+ if (this.contact_list && this.contact_list.rowcount > 0)
+ this.contact_list.focus();
+ break;
}
if (response.unlock)
diff --git a/program/js/list.js b/program/js/list.js
index 0bf5d568b..65d4a9260 100644
--- a/program/js/list.js
+++ b/program/js/list.js
@@ -274,11 +274,10 @@ clear: function(sel)
this.rows = {};
this.rowcount = 0;
+ this.last_selected = 0;
if (sel)
this.clear_selection();
- else
- this.last_selected = 0;
// reset scroll position (in Opera)
if (this.frame)
diff --git a/program/localization/en_US/labels.inc b/program/localization/en_US/labels.inc
index 0b5ff8c5a..874f19be2 100644
--- a/program/localization/en_US/labels.inc
+++ b/program/localization/en_US/labels.inc
@@ -591,11 +591,14 @@ $labels['arialabelmessagelistoptions'] = 'Message list display and sorting optio
$labels['arialabelmailimportdialog'] = 'Message import dialog';
$labels['arialabelmessagenav'] = 'Message navigation';
$labels['arialabelmessagebody'] = 'Message Body';
+$labels['arialabelmessageactions'] = 'Message actions';
$labels['arialabelcontactquicksearch'] = 'Contacts search form';
$labels['arialabelcontactsearchbox'] = 'Contact search input';
$labels['arialabelmessageheaders'] = 'Message headers';
$labels['arialabelcomposeoptions'] = 'Composition options';
$labels['arialabelresponsesmenu'] = 'Canned responses menu';
$labels['arialabelattachmentuploadform'] = 'Attachment upload form';
+$labels['arialabelattachmentpreview'] = 'Attachment preview';
+$labels['ariasummarycomposecontacts'] = 'List of contacts and groups to select as recipients';
?>
diff --git a/program/steps/mail/list_contacts.inc b/program/steps/mail/list_contacts.inc
index 0ee81135b..4f17beffd 100644
--- a/program/steps/mail/list_contacts.inc
+++ b/program/steps/mail/list_contacts.inc
@@ -110,7 +110,7 @@ else if (!empty($result) && $result->count > 0) {
$keyname = $row['_type'] == 'group' ? 'contactgroup' : 'contact';
$OUTPUT->command('add_contact_row', $row_id, array(
- $keyname => html::span(array('title' => $email), rcube::Q($name ? $name : $email) .
+ $keyname => html::a(array('title' => $email), rcube::Q($name ? $name : $email) .
($name && count($emails) > 1 ? '&nbsp;' . html::span('email', rcube::Q($email)) : '')
)), $classname);
}
diff --git a/program/steps/mail/search_contacts.inc b/program/steps/mail/search_contacts.inc
index d56581695..ccef32dd2 100644
--- a/program/steps/mail/search_contacts.inc
+++ b/program/steps/mail/search_contacts.inc
@@ -87,7 +87,7 @@ if (!empty($result) && $result->count > 0) {
$row_id = $row['ID'].'-'.$i;
$jsresult[$row_id] = format_email_recipient($email, $name);
$OUTPUT->command('add_contact_row', $row_id, array(
- 'contact' => html::span(array('title' => $email), rcube::Q($name ? $name : $email) .
+ 'contact' => html::a(array('title' => $email), rcube::Q($name ? $name : $email) .
($name && count($emails) > 1 ? '&nbsp;' . html::span('email', rcube::Q($email)) : '')
)), 'person');
}
diff --git a/skins/classic/mail.css b/skins/classic/mail.css
index 0a4653a3a..3310ac54f 100644
--- a/skins/classic/mail.css
+++ b/skins/classic/mail.css
@@ -780,6 +780,7 @@ table.messagelist.fixedcopy
-o-text-overflow: ellipsis;
border-bottom: 1px solid #EBEBEB;
cursor: default;
+ outline: none;
}
.messagelist tbody tr td a
diff --git a/skins/larry/styles.css b/skins/larry/styles.css
index d7ad74c01..add47324d 100644
--- a/skins/larry/styles.css
+++ b/skins/larry/styles.css
@@ -1187,6 +1187,12 @@ a.iconlink.upload {
outline: none;
}
+.listing tbody td a {
+ color: #376572;
+ text-shadow: 0px 1px 1px #fff;
+ text-decoration: none;
+}
+
.webkit .listing tbody td {
height: 14px;
}
diff --git a/skins/larry/templates/compose.html b/skins/larry/templates/compose.html
index 87993ed70..c643b36f5 100644
--- a/skins/larry/templates/compose.html
+++ b/skins/larry/templates/compose.html
@@ -52,7 +52,7 @@
<roundcube:button command="reset-search" id="searchreset" class="iconbutton reset" title="resetsearch" content=" " />
</div>
</div>
- <roundcube:object name="addressbooks" id="directorylist" class="treelist listing" />
+ <roundcube:object name="addressbooks" id="directorylist" class="treelist listing" summary="ariasummarycomposecontacts" />
<div class="scroller withfooter" tabindex="-1">
<roundcube:object name="addresslist" id="contacts-table" class="listing iconized" noheader="true" />
</div>
@@ -93,25 +93,25 @@
</tr><tr id="compose-cc">
<td class="title top">
<label for="_cc"><roundcube:label name="cc" /></label>
- <a href="#cc" onclick="return UI.hide_header_row('cc');" class="iconbutton cancel" title="<roundcube:label name='delete' /> <roundcube:label name='cc' />" tabindex="3">x</a>
+ <a href="#cc" onclick="return UI.hide_header_row('cc');" class="iconbutton cancel" title="<roundcube:label name='delete' />" tabindex="3"><roundcube:label name="delete" /> <roundcube:label name="cc" /></a>
</td>
<td class="editfield"><roundcube:object name="composeHeaders" part="cc" form="form" id="_cc" cols="70" rows="1" tabindex="1" /></td>
</tr><tr id="compose-bcc">
<td class="title top">
<label for="_bcc"><roundcube:label name="bcc" /></label>
- <a href="#bcc" onclick="return UI.hide_header_row('bcc');" class="iconbutton cancel" title="<roundcube:label name='delete' /> <roundcube:label name='bcc' />" tabindex="3">x</a>
+ <a href="#bcc" onclick="return UI.hide_header_row('bcc');" class="iconbutton cancel" title="<roundcube:label name='delete' />" tabindex="3"><roundcube:label name="delete" /> <roundcube:label name="bcc" /></a>
</td>
<td class="editfield"><roundcube:object name="composeHeaders" part="bcc" form="form" id="_bcc" cols="70" rows="1" tabindex="1" /></td>
</tr><tr id="compose-replyto">
<td class="title top">
<label for="_replyto"><roundcube:label name="replyto" /></label>
- <a href="#replyto" onclick="return UI.hide_header_row('replyto');" class="iconbutton cancel" title="<roundcube:label name='delete' /> <roundcube:label name='replyto' />" tabindex="3">x</a>
+ <a href="#replyto" onclick="return UI.hide_header_row('replyto');" class="iconbutton cancel" title="<roundcube:label name='delete' />" tabindex="3"><roundcube:label name="delete" /> <roundcube:label name="replyto" /></a>
</td>
<td class="editfield"><roundcube:object name="composeHeaders" part="replyto" form="form" id="_replyto" size="70" tabindex="1" /></td>
</tr><tr id="compose-followupto">
<td class="title top">
<label for="_followupto"><roundcube:label name="followupto" /></label>
- <a href="#followupto" onclick="return UI.hide_header_row('followupto');" class="iconbutton cancel" title="<roundcube:label name='delete' /> <roundcube:label name='followupto' />" tabindex="3">x</a>
+ <a href="#followupto" onclick="return UI.hide_header_row('followupto');" class="iconbutton cancel" title="<roundcube:label name='delete' />" tabindex="3"><roundcube:label name="delete" /> <roundcube:label name="followupto" /></a>
</td>
<td class="editfield"><roundcube:object name="composeHeaders" part="followupto" form="form" id="_followupto" size="70" tabindex="1" /></td>
</tr><tr>
diff --git a/skins/larry/templates/mail.html b/skins/larry/templates/mail.html
index 92b01e019..cf8ff2f7d 100644
--- a/skins/larry/templates/mail.html
+++ b/skins/larry/templates/mail.html
@@ -75,6 +75,7 @@
<div id="folderlist-footer" class="boxfooter">
<roundcube:button name="mailboxmenulink" id="mailboxmenulink" type="link" title="folderactions" class="listbutton groupactions" onclick="UI.toggle_popup('mailboxmenu',event);return false" innerClass="inner" content="&#9881;" aria-haspopup="true" aria-expanded="false"aria-owns="mailboxmenu-menu" />
<roundcube:if condition="env:quota" />
+ <span class="voice"><roundcube:label name="quota"></span>
<roundcube:object name="quotaDisplay" id="quotadisplay" class="countdisplay" display="text" />
<roundcube:endif />
</div>
diff --git a/skins/larry/templates/messagepart.html b/skins/larry/templates/messagepart.html
index 2df9c7b77..edf275f6e 100644
--- a/skins/larry/templates/messagepart.html
+++ b/skins/larry/templates/messagepart.html
@@ -29,9 +29,9 @@
</div>
<div id="messagepartcontainer" class="uibox" role="main" aria-labelledby="aria-label-messagepart">
- <h2 id="aria-label-messagepart" class="voice">Attachment preview</h2>
+ <h2 id="aria-label-messagepart" class="voice"><roundcube:label name="arialabelattachmentpreview" /></h2>
<div class="iframebox">
- <roundcube:object name="messagePartFrame" id="messagepartframe" frameborder="0" title="Attachment preview" />
+ <roundcube:object name="messagePartFrame" id="messagepartframe" frameborder="0" title="arialabelattachmentpreview" />
</div>
</div>
diff --git a/skins/larry/templates/messagepreview.html b/skins/larry/templates/messagepreview.html
index 97efdf3e7..82ecd7a43 100644
--- a/skins/larry/templates/messagepreview.html
+++ b/skins/larry/templates/messagepreview.html
@@ -10,7 +10,7 @@
<!-- record navigation -->
<div id="countcontrols" role="toolbar" aria-labelledby="aria-label-messagetoolbar">
-<h2 id="aria-label-messagetoolbar" class="voice">Message actions</h2>
+<h2 id="aria-label-messagetoolbar" class="voice"><roundcube:label name="arialabelmessageactions" /></h2>
<roundcube:if condition="env:optional_format=='text'" />
<span class="buttongroup">
<roundcube:button command="change-format" prop="html" type="link" class="button first changeformat html selected" innerClass="icon" title="changeformathtml" content="HTML" /><roundcube:button command="change-format" prop="text" type="link" class="button last changeformat text" classSel="button changeformat text pressed" innerClass="icon" title="changeformattext" content="Text" />
@@ -60,7 +60,7 @@
<roundcube:object name="messageAttachments" id="attachment-list" class="attachmentslist" />
</div>
<div class="leftcol" role="region" aria-labelledby="aria-label-messagebody">
-<h2 id="aria-label-messagebody" class="voice">Message Body</h2>
+<h2 id="aria-label-messagebody" class="voice"><roundcube:label name="arialabelmessagebody" /></h2>
<roundcube:object name="messageObjects" id="message-objects" />
<roundcube:object name="messageBody" id="messagebody" headertableclass="message-partheaders headers-table" />
</div>