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/js/app.js | 114 ++++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 73 insertions(+), 41 deletions(-) diff --git a/program/js/app.js b/program/js/app.js index bf163c6..b1feeb4 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -342,7 +342,16 @@ .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(); } @@ -444,9 +453,14 @@ if (this.gui_objects.identitieslist) { this.identity_list = new rcube_list_widget(this.gui_objects.identitieslist, - {multiselect:false, draggable:false, keyboard:false}); + {multiselect:false, draggable:false, keyboard:true}); this.identity_list .addEventListener('select', function(o) { ref.identity_select(o); }) + .addEventListener('keypress', function(o) { + if (o.key_pressed == o.ENTER_KEY) { + ref.identity_select(o); + } + }) .init() .focus(); @@ -454,9 +468,10 @@ this.identity_list.highlight_row(this.env.iid); } else if (this.gui_objects.sectionslist) { - this.sections_list = new rcube_list_widget(this.gui_objects.sectionslist, {multiselect:false, draggable:false, keyboard:false}); + this.sections_list = new rcube_list_widget(this.gui_objects.sectionslist, {multiselect:false, draggable:false, keyboard:true}); this.sections_list .addEventListener('select', function(o) { ref.section_select(o); }) + .addEventListener('keypress', function(o) { if (o.key_pressed == o.ENTER_KEY) ref.section_select(o); }) .init() .focus(); } @@ -464,7 +479,7 @@ this.init_subscription_list(); } else if (this.gui_objects.responseslist) { - this.responses_list = new rcube_list_widget(this.gui_objects.responseslist, {multiselect:false, draggable:false, keyboard:false}); + this.responses_list = new rcube_list_widget(this.gui_objects.responseslist, {multiselect:false, draggable:false, keyboard:true}); this.responses_list .addEventListener('select', function(list) { var win, id = list.get_single_selection(); @@ -602,7 +617,7 @@ { 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) @@ -1609,9 +1624,13 @@ if ($(target).closest('.ui-dialog, .ui-widget-overlay').length) return; - list = this.message_list || this.contact_list; - if (list && !rcube_mouse_is_over(e, list.list.parentNode)) - list.blur(); + // remove focus from list widgets + if (window.rcube_list_widget && rcube_list_widget._instances.length) { + $.each(rcube_list_widget._instances, function(i,list){ + if (list && !rcube_mouse_is_over(e, list.list.parentNode)) + list.blur(); + }); + } // reset 'pressed' buttons if (this.buttons_sel) { @@ -1623,7 +1642,7 @@ // reset popup menus; delayed to have updated menu_stack data window.setTimeout(function(e){ - var obj, skip, config, id, i; + var obj, skip, config, id, i, parents = $(target).parents(); for (i = ref.menu_stack.length - 1; i >= 0; i--) { id = ref.menu_stack[i]; obj = $('#' + id); @@ -1631,6 +1650,7 @@ if (obj.is(':visible') && target != obj.data('opener') && target != obj.get(0) // check if scroll bar was clicked (#1489832) + && !parents.is(obj.data('opener')) && id != skip && (obj.attr('data-editable') != 'true' || !$(target).parents('#' + id).length) && (obj.attr('data-sticky') != 'true' || !rcube_mouse_is_over(e, obj.get(0))) @@ -1647,9 +1667,12 @@ { // 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 +2425,6 @@ this.clear_message_list = function() { this.env.messages = {}; - this.last_selected = 0; this.show_contentframe(false); if (this.message_list) @@ -3417,9 +3439,7 @@ this.env.recipients_delimiter = this.env.recipients_separator + ' '; obj.keydown(function(e) { return ref.ksearch_keydown(e, this, props); }) - .attr('autocomplete', 'off') - .attr('aria-autocomplete', 'list') - .attr('aria-expanded', 'false'); + .attr({ 'autocomplete': 'off', 'aria-autocomplete': 'list', 'aria-expanded': 'false', 'role': 'combobox' }); }; this.submit_messageform = function(draft) @@ -3490,6 +3510,8 @@ 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 @@ -4562,9 +4584,9 @@ } if (node) { - $(node).addClass('selected').removeAttr('aria-selected', 'true'); + $(node).addClass('selected').attr('aria-selected', 'true'); this.ksearch_selected = node._rcm_id; - $(this.ksearch_input).attr('aria-activedecendant', 'rcmkSearchItem' + this.ksearch_selected); + $(this.ksearch_input).attr('aria-activedescendant', 'rcmkSearchItem' + this.ksearch_selected); } }; @@ -4745,17 +4767,18 @@ } if (ul.childNodes.length) { - this.ksearch_pane.show(); - // select the first - if (!this.env.contacts.length) { - this.ksearch_select($('li:first', ul).get(0)); - } - // set the right aria-* attributes to the input field $(this.ksearch_input) .attr('aria-haspopup', 'true') .attr('aria-expanded', 'true') - .attr('aria-owns', 'rcmKSearchpane') + .attr('aria-owns', 'rcmKSearchpane'); + + this.ksearch_pane.show(); + + // select the first + if (!this.env.contacts.length) { + this.ksearch_select($('li:first', ul).get(0)); + } } if (len) @@ -4794,7 +4817,7 @@ $(this.ksearch_input) .attr('aria-haspopup', 'false') .attr('aria-expanded', 'false') - .removeAttr('aria-activedecendant') + .removeAttr('aria-activedescendant') .removeAttr('aria-owns'); this.ksearch_destroy(); @@ -5001,6 +5024,7 @@ // add link to pop back to parent group if (this.env.address_group_stack.length > 1) { $('<a href="#list">...</a>') + .attr('title', this.gettext('uponelevel')) .addClass('poplink') .appendTo(boxtitle) .click(function(e){ return ref.command('popgroup','',this); }); @@ -5537,6 +5561,7 @@ if (appendcontainer.length && appendcontainer.get(0).nodeName == 'FIELDSET') { var input, colprop = this.env.coltypes[col], + input_id = 'ff_' + col + (colprop.count || 0), row = $('<div>').addClass('row'), cell = $('<div>').addClass('contactfieldcontent data'), label = $('<div>').addClass('contactfieldlabel label'); @@ -5544,13 +5569,13 @@ if (colprop.subtypes_select) label.html(colprop.subtypes_select); else - label.html(colprop.label); + label.html('<label for="' + input_id + '">' + colprop.label + '</label>'); var name_suffix = colprop.limit != 1 ? '[]' : ''; if (colprop.type == 'text' || colprop.type == 'date') { input = $('<input>') .addClass('ff_'+col) - .attr({type: 'text', name: '_'+col+name_suffix, size: colprop.size}) + .attr({type: 'text', name: '_'+col+name_suffix, size: colprop.size, id: input_id}) .appendTo(cell); this.init_edit_field(col, input); @@ -5561,7 +5586,7 @@ else if (colprop.type == 'textarea') { input = $('<textarea>') .addClass('ff_'+col) - .attr({ name: '_'+col+name_suffix, cols:colprop.size, rows:colprop.rows }) + .attr({ name: '_'+col+name_suffix, cols:colprop.size, rows:colprop.rows, id: input_id }) .appendTo(cell); this.init_edit_field(col, input); @@ -5596,7 +5621,7 @@ else if (colprop.type == 'select') { input = $('<select>') .addClass('ff_'+col) - .attr('name', '_'+col+name_suffix) + .attr({ 'name': '_'+col+name_suffix, id: input_id }) .appendTo(cell); var options = input.attr('options'); @@ -5903,7 +5928,7 @@ this.last_sub_rx = RegExp('['+delim+']?[^'+delim+']+$'); this.subscription_list = new rcube_list_widget(this.gui_objects.subscriptionlist, - {multiselect:false, draggable:true, keyboard:false, toggleselect:true}); + {multiselect:false, draggable:true, keyboard:true, toggleselect:true}); this.subscription_list .addEventListener('select', function(o){ ref.subscription_select(o); }) .addEventListener('dragstart', function(o){ ref.drag_active = true; }) @@ -5912,7 +5937,8 @@ row.obj.onmouseover = function() { ref.focus_subscription(row.id); }; row.obj.onmouseout = function() { ref.unfocus_subscription(row.id); }; }) - .init(); + .init() + .focus(); $('#mailboxroot') .mouseover(function(){ ref.focus_subscription(this.id); }) @@ -6685,7 +6711,7 @@ tr = document.createElement('tr'); for (c=0, len=repl.length; c < len; c++) { - cell = document.createElement('td'); + cell = document.createElement('th'); cell.innerHTML = repl[c].html || ''; if (repl[c].id) cell.id = repl[c].id; if (repl[c].className) cell.className = repl[c].className; @@ -6927,13 +6953,7 @@ container.data('callback')($(this).data('id')); return false; }); -/* - // hide selector on click out of selector element - var fn = function(e) { if (e.target != container.get(0)) container.hide(); }; - $(document.body).on('mouseup', fn); - $('iframe').contents().on('mouseup', fn) - .load(function(e) { try { $(this).contents().on('mouseup', fn); } catch(e) {}; }); -*/ + this.folder_selector_element = container; } @@ -6957,6 +6977,10 @@ keyboard = rcube_event.is_keyboard(event), align = obj.attr('data-align') || '', stack = false; + + // find "real" button element + if (ref.get(0).tagName != 'A' && ref.closest('a').length) + ref = ref.closest('a'); if (typeof prop == 'string') prop = { menu:name }; @@ -7405,7 +7429,8 @@ 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 +7442,18 @@ 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) -- Gitblit v1.9.1