diff options
-rw-r--r-- | program/include/rcmail_output_html.php | 2 | ||||
-rw-r--r-- | program/js/app.js | 31 | ||||
-rw-r--r-- | program/js/list.js | 2 | ||||
-rw-r--r-- | skins/larry/addressbook.css | 17 | ||||
-rw-r--r-- | skins/larry/mail.css | 29 | ||||
-rw-r--r-- | skins/larry/styles.css | 30 | ||||
-rw-r--r-- | skins/larry/templates/addressbook.html | 2 | ||||
-rw-r--r-- | skins/larry/templates/compose.html | 66 | ||||
-rw-r--r-- | skins/larry/ui.js | 13 |
9 files changed, 121 insertions, 71 deletions
diff --git a/program/include/rcmail_output_html.php b/program/include/rcmail_output_html.php index ff660a4df..19a8d142c 100644 --- a/program/include/rcmail_output_html.php +++ b/program/include/rcmail_output_html.php @@ -1135,6 +1135,8 @@ EOF; $attrib['role'] = 'button'; } if (!empty($attrib['class']) && !empty($attrib['classact']) || !empty($attrib['imagepas']) && !empty($attrib['imageact'])) { + if (array_key_exists('tabindex', $attrib)) + $attrib['data-tabindex'] = $attrib['tabindex']; $attrib['tabindex'] = '-1'; // disable button by default $attrib['aria-disabled'] = 'true'; } diff --git a/program/js/app.js b/program/js/app.js index 11236d0cb..4c9462afa 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -300,10 +300,12 @@ function rcube_webmail() $('a.insertresponse', this.gui_objects.responseslist) .attr('unselectable', 'on') .mousedown(function(e){ return rcube_event.cancel(e); }) - .mouseup(function(e){ - ref.command('insert-response', $(this).attr('rel')); - $(document.body).trigger('mouseup'); // hides the menu - return rcube_event.cancel(e); + .bind('mouseup keypress', function(e){ + if (e.type == 'mouseup' || rcube_event.get_keycode(e) == 13) { + ref.command('insert-response', $(this).attr('rel')); + $(document.body).trigger('mouseup'); // hides the menu + return rcube_event.cancel(e); + } }); // avoid textarea loosing focus when hitting the save-response button/link @@ -337,11 +339,12 @@ function rcube_webmail() // init address book widget if (this.gui_objects.contactslist) { this.contact_list = new rcube_list_widget(this.gui_objects.contactslist, - { multiselect:true, draggable:false, keyboard:false }); + { multiselect:true, draggable:false, keyboard:true }); this.contact_list .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'); }) .init(); } @@ -3600,10 +3603,12 @@ function rcube_webmail() .mousedown(function(e){ return rcube_event.cancel(e); }) - .mouseup(function(e){ - ref.command('insert-response', key); - $(document.body).trigger('mouseup'); // hides the menu - return rcube_event.cancel(e); + .bind('mouseup keypress', function(e){ + if (e.type == 'mouseup' || rcube_event.get_keycode(e) == 13) { + ref.command('insert-response', $(this).attr('rel')); + $(document.body).trigger('mouseup'); // hides the menu + return rcube_event.cancel(e); + } }); } }; @@ -6195,7 +6200,7 @@ function rcube_webmail() // set button to a specific state this.set_button = function(command, state) { - var n, button, obj, a_buttons = this.buttons[command], + var n, button, obj, $obj, a_buttons = this.buttons[command], len = a_buttons ? a_buttons.length : 0; for (n=0; n<len; n++) { @@ -6235,8 +6240,9 @@ function rcube_webmail() $(obj).button('option', 'disabled', state == 'pas'); } else { - $(obj) - .attr('tabindex', state == 'pas' || state == 'sel' ? '-1' : '0') + $obj = $(obj); + $obj + .attr('tabindex', state == 'pas' || state == 'sel' ? '-1' : ($obj.attr('data-tabindex') || '0')) .attr('aria-disabled', state == 'pas' || state == 'sel' ? 'true' : 'false'); } } @@ -7147,6 +7153,7 @@ 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(); this.triggerEvent('listupdate', { folder:this.env.source, rowcount:this.contact_list.rowcount }); } } diff --git a/program/js/list.js b/program/js/list.js index 14dfde379..6a0c5b3b6 100644 --- a/program/js/list.js +++ b/program/js/list.js @@ -558,6 +558,8 @@ click_row: function(e, id) } this.rows[id].clicked = now; + this.focus(); + return false; }, diff --git a/skins/larry/addressbook.css b/skins/larry/addressbook.css index bfdd68127..75dc0d8c3 100644 --- a/skins/larry/addressbook.css +++ b/skins/larry/addressbook.css @@ -138,23 +138,6 @@ background: url(images/listicons.png) -2px -1180px no-repeat; } -/* This padding-left should be equal to the focused border-left + the focused padding-left */ -#contacts-table thead tr td:first-child, -#contacts-table tbody tr td:first-child { - border-left: 0; - padding-left: 36px; -} - -/* because of border-collapse, we make the left border twice what we want it to be - half will be hidden to the left */ -#contacts-table tbody tr.focused > td:first-child { - border-left: 2px solid #b0ccd7; - padding-left: 34px; -} - -#contacts-table tbody tr.selected.focused > td:first-child { - border-left-color: #9ec2d0; -} - #contacts-table .contact td.name { background-position: 6px -1603px; } diff --git a/skins/larry/mail.css b/skins/larry/mail.css index ff590c45d..c5919ffe3 100644 --- a/skins/larry/mail.css +++ b/skins/larry/mail.css @@ -1358,13 +1358,19 @@ div.message-partheaders .headers-table td.header { margin-left: 0.5em; } -#compose-contacts li a, #contacts-table td { - background: url(images/listicons.png) -100px 0 no-repeat; +#compose-contacts li a, +#contacts-table td { + background-image: url(images/listicons.png); + background-position: -100px 0; + background-repeat: no-repeat; overflow: hidden; - padding-left: 36px; text-overflow: ellipsis; } +#compose-contacts li a { + padding-left: 36px; +} + #contacts-table td.contactgroup a { color: #376572; text-decoration: none; @@ -1386,6 +1392,7 @@ div.message-partheaders .headers-table td.header { background-position: 6px -766px; } +#compose-contacts li.addressbook a:focus, #compose-contacts li.addressbook.selected a { background-position: 6px -791px; } @@ -1394,20 +1401,36 @@ div.message-partheaders .headers-table td.header { background-position: 6px -1555px; } +#contacts-table.focus tr.focused td.contactgroup { + background-position: 4px -1555px; +} + #contacts-table tr.unfocused td.contactgroup, #contacts-table tr.selected td.contactgroup { background-position: 6px -1579px; } +#contacts-table.focus tr.selected.focused td.contactgroup { + background-position: 4px -1579px; +} + #contacts-table td.contact { background-position: 6px -1603px; } +#contacts-table.focus tr.focused td.contact { + background-position: 4px -1603px; +} + #contacts-table tr.unfocused td.contact, #contacts-table tr.selected td.contact { background-position: 6px -1627px; } +#contacts-table.focus tr.selected.focused td.contact { + background-position: 4px -1627px; +} + #compose-content { position: absolute; top: 0; diff --git a/skins/larry/styles.css b/skins/larry/styles.css index cbff87bec..e1dbeeaa9 100644 --- a/skins/larry/styles.css +++ b/skins/larry/styles.css @@ -1190,6 +1190,36 @@ a.iconlink.upload { height: 14px; } +/* This padding-left minus the focused padding left should be half of the focused border-left */ +.listing thead tr td:first-child, +.listing tbody tr td:first-child { + border-left: 0; + padding-left: 6px; +} + +.listing.iconized thead tr td:first-child, +.listing.iconized tbody tr td:first-child { + padding-left: 36px; +} + +/* because of border-collapse, we make the left border twice what we want it to be - half will be hidden to the left */ +.listing.focus tbody tr.focused > td:first-child { + border-left: 2px solid #b0ccd7; + padding-left: 4px; +} + +.listing.iconized.focus tbody tr.focused > td:first-child { + padding-left: 34px; +} + +.listing.focus tbody tr.selected.focused > td:first-child { + border-left-color: #9ec2d0; +} + +.listing.inconized.focus tr.focused td:first-child { + padding-left: 34px; +} + .listbox .listitem.selected, .listbox .tablink.selected, .listbox .listitem.selected > a, diff --git a/skins/larry/templates/addressbook.html b/skins/larry/templates/addressbook.html index 97efdc6f3..0b1009f7e 100644 --- a/skins/larry/templates/addressbook.html +++ b/skins/larry/templates/addressbook.html @@ -54,7 +54,7 @@ <div id="addresslist" class="uibox listbox"> <roundcube:object name="addresslisttitle" label="contacts" tag="h2" class="boxtitle" /> <div class="scroller withfooter"> -<roundcube:object name="addresslist" id="contacts-table" class="listing" noheader="true" /> +<roundcube:object name="addresslist" id="contacts-table" class="listing iconized" noheader="true" /> </div> <div class="boxfooter"> <roundcube:button command="add" type="link" title="newcontact" class="listbutton add disabled" classAct="listbutton add" innerClass="inner" content="+" /><roundcube:button command="delete" type="link" title="deletecontact" class="listbutton delete disabled" classAct="listbutton delete" innerClass="inner" content="x" /><roundcube:button command="group-remove-selected" type="link" title="groupremoveselected" class="listbutton removegroup disabled" classAct="listbutton removegroup" innerClass="inner" content="-" /> diff --git a/skins/larry/templates/compose.html b/skins/larry/templates/compose.html index 07d935795..5eedca204 100644 --- a/skins/larry/templates/compose.html +++ b/skins/larry/templates/compose.html @@ -18,21 +18,21 @@ <!-- toolbar --> <h2 id="aria-label-toolbar" class="voice">Application toolbar</h2> <div id="messagetoolbar" class="toolbar fullwidth" role="toolbar" aria-labelledby="aria-label-toolbar"> - <roundcube:button command="list" type="link" class="button back disabled" classAct="button back" classSel="button back pressed" label="cancel" condition="!env:extwin" /> - <roundcube:button command="close" type="link" class="button close disabled" classAct="button close" classSel="button close pressed" label="cancel" condition="env:extwin" /> + <roundcube:button command="list" type="link" class="button back disabled" classAct="button back" label="cancel" condition="!env:extwin" tabindex="2" /> + <roundcube:button command="close" type="link" class="button close disabled" classAct="button close" label="cancel" condition="env:extwin" tabindex="2" /> <span class="spacer"></span> - <roundcube:button command="send" type="link" class="button send" classAct="button send" classSel="button send pressed" label="send" title="sendmessage" /> - <roundcube:button command="savedraft" type="link" class="button savedraft" classAct="button savedraft" classSel="button savedraft pressed" label="save" title="savemessage" /> + <roundcube:button command="send" type="link" class="button send disabled" classAct="button send" label="send" title="sendmessage" tabindex="2" /> + <roundcube:button command="savedraft" type="link" class="button savedraft disabled" classAct="button savedraft" label="save" title="savemessage" tabindex="2" /> <span class="spacer"></span> <roundcube:if condition="config:enable_spellcheck" /> <span class="dropbutton"> - <roundcube:button command="spellcheck" type="link" class="button spellcheck disabled" classAct="button spellcheck" classSel="button spellcheck pressed" label="spellcheck" title="checkspelling" /> - <a href="#languages" class="dropbuttontip" id="spellmenulink" onclick="UI.toggle_popup('spellmenu',event);return false" aria-haspopup="true"></a> + <roundcube:button command="spellcheck" type="link" class="button spellcheck disabled" classAct="button spellcheck" classSel="button spellcheck pressed" label="spellcheck" title="checkspelling" tabindex="2" /> + <a href="#languages" class="dropbuttontip" id="spellmenulink" onclick="UI.toggle_popup('spellmenu',event);return false" aria-haspopup="true" tabindex="2"></a> </span> <roundcube:endif /> - <roundcube:button name="addattachment" type="link" class="button attach" classAct="button attach" classSel="button attach pressed" label="attach" title="addattachment" onclick="UI.show_uploadform();return false" /> - <roundcube:button command="insert-sig" type="link" class="button insertsig disabled" classAct="button insertsig" classSel="button insertsig pressed" label="signature" title="insertsignature" /> - <a href="#responses" class="button responses" label="responses" title="<roundcube:label name='insertresponse' />" id="responsesmenulink" unselectable="on" onmousedown="return false" onclick="UI.toggle_popup('responsesmenu',event);return false" aria-haspopup="true" aria-owns="textresponsesmenu"><roundcube:label name="responses" /></a> + <roundcube:button name="addattachment" type="link" class="button attach" label="attach" title="addattachment" onclick="UI.show_uploadform(event);return false" aria-haspopup="true" tabindex="2" /> + <roundcube:button command="insert-sig" type="link" class="button insertsig disabled" classAct="button insertsig" label="signature" title="insertsignature" tabindex="2" /> + <a href="#responses" class="button responses" label="responses" title="<roundcube:label name='insertresponse' />" id="responsesmenulink" unselectable="on" onmousedown="return false" onclick="UI.toggle_popup('responsesmenu',event);return false" tabindex="2" aria-haspopup="true" aria-owns="textresponsesmenu"><roundcube:label name="responses" /></a> <roundcube:container name="toolbar" id="compose-toolbar" /> </div> @@ -52,9 +52,9 @@ <roundcube:button command="reset-search" id="searchreset" class="iconbutton reset" title="resetsearch" content=" " /> </div> </div> - <roundcube:object name="addressbooks" id="directorylist" class="listing" /> - <div class="scroller withfooter"> - <roundcube:object name="addresslist" id="contacts-table" class="listing" noheader="true" /> + <roundcube:object name="addressbooks" id="directorylist" class="treelist listing" /> + <div class="scroller withfooter" tabindex="-1"> + <roundcube:object name="addresslist" id="contacts-table" class="listing iconized" noheader="true" /> </div> <div class="boxfooter"> <roundcube:button command="add-recipient" prop="to" type="link" title="to" class="listbutton addto disabled" classAct="listbutton addto" innerClass="inner" content="To+" /><roundcube:button command="add-recipient" prop="cc" type="link" title="cc" class="listbutton addcc disabled" classAct="listbutton addcc" innerClass="inner" content="Cc+" /><roundcube:button command="add-recipient" prop="bcc" type="link" title="bcc" class="listbutton addbcc disabled" classAct="listbutton addbcc" innerClass="inner" content="Bcc+" /> @@ -89,42 +89,42 @@ </td> </tr><tr> <td class="title top"><label for="_to"><roundcube:label name="to" /></label></td> - <td class="editfield"><roundcube:object name="composeHeaders" part="to" form="form" id="_to" cols="70" rows="1" tabindex="2" /></td> + <td class="editfield"><roundcube:object name="composeHeaders" part="to" form="form" id="_to" cols="70" rows="1" tabindex="1" aria-required="true" /></td> </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' />">x</a> + <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> </td> - <td class="editfield"><roundcube:object name="composeHeaders" part="cc" form="form" id="_cc" cols="70" rows="1" tabindex="3" /></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' />">x</a> + <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> </td> - <td class="editfield"><roundcube:object name="composeHeaders" part="bcc" form="form" id="_bcc" cols="70" rows="1" tabindex="4" /></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' />">x</a> + <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> </td> - <td class="editfield"><roundcube:object name="composeHeaders" part="replyto" form="form" id="_replyto" size="70" tabindex="5" /></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' />">x</a> + <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> </td> - <td class="editfield"><roundcube:object name="composeHeaders" part="followupto" form="form" id="_followupto" size="70" tabindex="7" /></td> + <td class="editfield"><roundcube:object name="composeHeaders" part="followupto" form="form" id="_followupto" size="70" tabindex="1" /></td> </tr><tr> <td></td> <td class="formlinks"> - <a href="#cc" onclick="return UI.show_header_row('cc')" id="cc-link" class="iconlink add"><roundcube:label name="addcc" /></a> - <a href="#bcc" onclick="return UI.show_header_row('bcc')" id="bcc-link" class="iconlink add"><roundcube:label name="addbcc" /></a> - <a href="#reply-to" onclick="return UI.show_header_row('replyto')" id="replyto-link" class="iconlink add"><roundcube:label name="addreplyto" /></a> - <a href="#followup-to" onclick="return UI.show_header_row('followupto')" id="followupto-link" class="iconlink add"><roundcube:label name="addfollowupto" /></a> + <a href="#cc" onclick="return UI.show_header_row('cc')" id="cc-link" class="iconlink add" tabindex="3"><roundcube:label name="addcc" /></a> + <a href="#bcc" onclick="return UI.show_header_row('bcc')" id="bcc-link" class="iconlink add" tabindex="3"><roundcube:label name="addbcc" /></a> + <a href="#reply-to" onclick="return UI.show_header_row('replyto')" id="replyto-link" class="iconlink add" tabindex="3"><roundcube:label name="addreplyto" /></a> + <a href="#followup-to" onclick="return UI.show_header_row('followupto')" id="followupto-link" class="iconlink add" tabindex="3"><roundcube:label name="addfollowupto" /></a> </td> </tr><tr> <td class="title"><label for="compose-subject"><roundcube:label name="subject" /></label></td> - <td class="editfield"><roundcube:object name="composeSubject" id="compose-subject" form="form" tabindex="8" /></td> + <td class="editfield"><roundcube:object name="composeSubject" id="compose-subject" form="form" tabindex="1" /></td> </tr> </tbody> </table> @@ -139,24 +139,24 @@ <roundcube:if condition="!in_array('htmleditor', (array)config:dont_override)" /> <span class="composeoption"> <label><roundcube:label name="editortype" /> - <roundcube:object name="editorSelector" editorid="composebody" tabindex="14" /></label> + <roundcube:object name="editorSelector" editorid="composebody" tabindex="4" /></label> </span> <roundcube:endif /> <span class="composeoption"> <label for="rcmcomposepriority"><roundcube:label name="priority" /> - <roundcube:object name="prioritySelector" form="form" id="rcmcomposepriority" /></label> + <roundcube:object name="prioritySelector" form="form" id="rcmcomposepriority" tabindex="4" /></label> </span> <span class="composeoption"> - <label><roundcube:object name="receiptCheckBox" form="form" id="rcmcomposereceipt" /> <roundcube:label name="returnreceipt" /></label> + <label><roundcube:object name="receiptCheckBox" form="form" id="rcmcomposereceipt" tabindex="4" /> <roundcube:label name="returnreceipt" /></label> </span> <roundcube:if condition="config:smtp_server != ''" /> <span class="composeoption"> - <label><roundcube:object name="dsnCheckBox" form="form" id="rcmcomposedsn" /> <roundcube:label name="dsn" /></label> + <label><roundcube:object name="dsnCheckBox" form="form" id="rcmcomposedsn" tabindex="4" /> <roundcube:label name="dsn" /></label> </span> <roundcube:endif /> <roundcube:if condition="!config:no_save_sent_messages" /> <span class="composeoption"> - <label><roundcube:label name="savesentmessagein" /> <roundcube:object name="storetarget" maxlength="30" style="max-width:12em" /></label> + <label><roundcube:label name="savesentmessagein" /> <roundcube:object name="storetarget" maxlength="30" style="max-width:12em" tabindex="4" /></label> </span> <roundcube:endif /> <roundcube:container name="composeoptions" id="composeoptions" /> @@ -167,12 +167,12 @@ <!-- message compose body --> <div id="composeview-bottom"> <div id="composebodycontainer"> - <roundcube:object name="composeBody" id="composebody" form="form" cols="70" rows="20" tabindex="9" /> + <roundcube:object name="composeBody" id="composebody" form="form" cols="70" rows="20" tabindex="1" /> </div> <div id="compose-attachments" class="rightcol" role="region"> <h2 id="aria-label-composeoptions" class="voice"><roundcube:label name="attachments" /></h2> <div style="text-align:center; margin-bottom:20px"> - <roundcube:button name="addattachment" type="input" class="button" classSel="button pressed" label="addattachment" onclick="UI.show_uploadform();return false" /> + <roundcube:button name="addattachment" type="input" class="button" classSel="button pressed" label="addattachment" onclick="UI.show_uploadform(event);return false" tabindex="1" /> </div> <roundcube:object name="composeAttachmentList" id="attachment-list" class="attachmentslist" /> <roundcube:object name="fileDropArea" id="compose-attachments" /> diff --git a/skins/larry/ui.js b/skins/larry/ui.js index 922bb2119..1d38ceae1 100644 --- a/skins/larry/ui.js +++ b/skins/larry/ui.js @@ -195,11 +195,13 @@ function rcube_mail_ui() } } - $('#composeoptionstoggle').click(function(){ + $('#composeoptionstoggle').click(function(e){ $('#composeoptionstoggle').toggleClass('remove'); $('#composeoptions').toggle(); layout_composeview(); save_pref('composeoptions', $('#composeoptions').is(':visible') ? '1' : '0'); + if (!rcube_event.is_keyboard(e)) + this.blur(); return false; }).css('cursor', 'pointer'); @@ -1071,7 +1073,7 @@ function rcube_mail_ui() }); } - function show_uploadform() + function show_uploadform(e) { var $dialog = $('#upload-dialog'); @@ -1097,6 +1099,10 @@ function rcube_mail_ui() resizable: false, closeOnEscape: true, title: $dialog.attr('title'), + open: function(e) { + if (!document.all) + $('input[type=file]', $dialog).first().click(); + }, close: function() { try { $('#upload-dialog form').get(0).reset(); } catch(e){ } // ignore errors @@ -1106,9 +1112,6 @@ function rcube_mail_ui() }, width: 480 }).show(); - - if (!document.all) - $('input[type=file]', $dialog).first().click(); } function add_uploadfile(e) |