Commit 5c01e745 by jareerahsan Committed by GitHub

Merge pull request #13301 from edx/jareer/ECOM-4945

Fixed Shift-Tab on menu and ARIA roles, groups
parents f226d438 c2c17c11
$(document).ready(function() { (function(require) {
'use strict'; 'use strict';
// define variables for code legibility require([
var dropdownMenuToggle = $('.dropdown'); 'jquery',
var dropdownMenu = $('.dropdown-menu'); 'edx-ui-toolkit/js/utils/constants'
var menuItems = dropdownMenu.find('a'); ], function($, constants) {
// define variables for code legibility
var $dropdownMenuToggle = $('.dropdown');
var $dropdownMenu = $('.dropdown-menu');
var menuItems = $dropdownMenu.find('.dropdown-menuitem');
// bind menu toggle click for later use // bind menu toggle click for later use
dropdownMenuToggle.toggle(function() { $dropdownMenuToggle.toggle(function() {
dropdownMenu.addClass('expanded').find('a').first().focus(); $dropdownMenu.addClass('expanded').find('.dropdown-menuitem').first()
dropdownMenuToggle.addClass('active').attr('aria-expanded', 'true'); .focus();
}, function() { $dropdownMenuToggle.addClass('active').attr('aria-expanded', 'true');
dropdownMenu.removeClass('expanded'); }, function() {
dropdownMenuToggle.removeClass('active').attr('aria-expanded', 'false').focus(); $dropdownMenu.removeClass('expanded');
}); $dropdownMenuToggle.removeClass('active').attr('aria-expanded', 'false').focus();
});
// catch keypresses when focused on dropdownMenuToggle (we only care about spacebar keypresses here)
dropdownMenuToggle.on('keydown', function(event) {
// if space key pressed
if (event.which == 32) {
dropdownMenuToggle.click();
event.preventDefault();
}
});
// catch keypresses when inside dropdownMenu (we want to catch spacebar; escape; up arrow or shift+tab; and down arrow or tab) // catch keypresses when focused on dropdownMenuToggle (we only care about spacebar keypresses here)
dropdownMenu.on('keydown', function(event) { $dropdownMenuToggle.on('keydown', function(event) {
catchKeyPress($(this), event); // if space key pressed
}); if (event.which === constants.keyCodes.space) {
$dropdownMenuToggle.click();
event.preventDefault();
}
});
function catchKeyPress(object, event) { function catchKeyPress(object, event) {
// get currently focused item // get currently focused item
var focusedItem = jQuery(':focus'); var focusedItem = jQuery(':focus');
// get the number of focusable items // get the number of focusable items
var numberOfMenuItems = menuItems.length; var numberOfMenuItems = menuItems.length;
// get the index of the currently focused item // get the index of the currently focused item
var focusedItemIndex = menuItems.index(focusedItem); var focusedItemIndex = menuItems.index(focusedItem);
// var to store next focused item index // var to store next focused item index
var itemToFocusIndex; var itemToFocusIndex;
// if space key pressed // if space key pressed
if (event.which == 32) { if (event.which === constants.keyCodes.space) {
dropdownMenuToggle.click(); $dropdownMenuToggle.click();
event.preventDefault(); event.preventDefault();
} }
// if escape key pressed
if (event.which == 27) {
dropdownMenuToggle.click();
event.preventDefault();
}
// if up arrow key pressed or shift+tab // if escape key pressed
if (event.which == 38 || (event.which == 9 && event.shiftKey)) { if (event.which === constants.keyCodes.esc) {
// if first item go to last $dropdownMenuToggle.click();
if (focusedItemIndex === 0) { event.preventDefault();
menuItems.last().focus();
} else {
itemToFocusIndex = focusedItemIndex - 1;
menuItems.get(itemToFocusIndex).focus();
} }
event.preventDefault();
}
// if down arrow key pressed or tab key // if up arrow key pressed or shift+tab else down key or tab is pressed
if (event.which == 40 || event.which == 9) { if (event.which === constants.keyCodes.up || event.which === constants.keyCodes.left ||
// if last item go to first (event.which === constants.keyCodes.tab && event.shiftKey)) {
if (focusedItemIndex == numberOfMenuItems - 1) { // if first item go to last
menuItems.first().focus(); if (focusedItemIndex === 0) {
} else { menuItems.last().focus();
itemToFocusIndex = focusedItemIndex + 1; } else {
menuItems.get(itemToFocusIndex).focus(); itemToFocusIndex = focusedItemIndex - 1;
menuItems.get(itemToFocusIndex).focus();
}
event.preventDefault();
} else if (event.which === constants.keyCodes.down || event.which === constants.keyCodes.right ||
event.which === constants.keyCodes.tab) {
// if last item go to first
if (focusedItemIndex === numberOfMenuItems - 1) {
menuItems.first().focus();
} else {
itemToFocusIndex = focusedItemIndex + 1;
menuItems.get(itemToFocusIndex).focus();
}
event.preventDefault();
} }
event.preventDefault();
} }
}
}); // catch keypresses when inside dropdownMenu
// (we want to catch spacebar; escape; up arrow or shift+tab; and down arrow or tab)
$dropdownMenu.on('keydown', function(event) {
catchKeyPress($(this), event);
});
});
}).call(this, require || RequireJS.require);
...@@ -20,18 +20,20 @@ from openedx.core.djangoapps.user_api.accounts.image_helpers import get_profile_ ...@@ -20,18 +20,20 @@ from openedx.core.djangoapps.user_api.accounts.image_helpers import get_profile_
<img class="menu-image" src="${profile_image_url}" alt=""> <img class="menu-image" src="${profile_image_url}" alt="">
${username} ${username}
</a> </a>
<button type="button" class="menu-button button-more has-dropdown js-dropdown-button" aria-haspopup="true" aria-expanded="false" aria-controls="${_("Usermenu")}"> <div role="group" aria-label="User menu">
<span class="icon fa fa-caret-down" aria-hidden="true"></span> <button type="button" class="menu-button button-more has-dropdown js-dropdown-button" aria-expanded="false" aria-controls="${_("Usermenu")}">
<span class="sr-only">${_("Usermenu dropdown")}</span> <span class="icon fa fa-caret-down" aria-hidden="true"></span>
</button> <span class="sr-only">${_("Usermenu dropdown")}</span>
<ul class="dropdown-menu list-divided is-hidden" id="${_("Usermenu")}" tabindex="-1"> </button>
<%block name="navigation_dropdown_menu_links" > <ul class="dropdown-menu list-divided is-hidden" id="${_("Usermenu")}" tabindex="-1">
<li class="dropdown-item item has-block-link"><a href="${reverse('dashboard')}" class="action">${_("Dashboard")}</a></li> <%block name="navigation_dropdown_menu_links" >
<li class="dropdown-item item has-block-link"><a href="${reverse('learner_profile', kwargs={'username': user.username})}" class="action">${_("Profile")}</a></li> <li class="dropdown-item item has-block-link"><a href="${reverse('dashboard')}" class="action dropdown-menuitem">${_("Dashboard")}</a></li>
<li class="dropdown-item item has-block-link"><a href="${reverse('account_settings')}" class="action">${_("Account")}</a></li> <li class="dropdown-item item has-block-link"><a href="${reverse('learner_profile', kwargs={'username': user.username})}" class="action dropdown-menuitem">${_("Profile")}</a></li>
</%block> <li class="dropdown-item item has-block-link"><a href="${reverse('account_settings')}" class="action dropdown-menuitem">${_("Account")}</a></li>
<li class="dropdown-item item has-block-link"><a href="${reverse('logout')}" role="menuitem" class="action">${_("Sign Out")}</a></li> </%block>
</ul> <li class="dropdown-item item has-block-link"><a href="${reverse('logout')}" role="menuitem" class="action dropdown-menuitem">${_("Sign Out")}</a></li>
</ul>
</div>
</div> </div>
% else: % else:
<ol class="user"> <ol class="user">
...@@ -47,11 +49,13 @@ from openedx.core.djangoapps.user_api.accounts.image_helpers import get_profile_ ...@@ -47,11 +49,13 @@ from openedx.core.djangoapps.user_api.accounts.image_helpers import get_profile_
</a> </a>
</li> </li>
<li class="primary"> <li class="primary">
<button class="dropdown" aria-haspopup="true" aria-expanded="false"><span class="sr">${_("More options dropdown")}</span><span class="fa fa-sort-desc" aria-hidden="true"></span></button> <div role="group" aria-label="User menu">
<ul class="dropdown-menu" aria-label="More Options" role="menu"> <button class="dropdown" aria-expanded="false"><span class="sr">${_("More options dropdown")}</span><span class="fa fa-sort-desc" aria-hidden="true"></span></button>
${navigation_dropdown_menu_links()} <ul class="dropdown-menu" aria-label="More Options" role="menu">
<li class="item"><a href="${reverse('logout')}" role="menuitem">${_("Sign Out")}</a></li> ${navigation_dropdown_menu_links()}
</ul> <li class="item"><a href="${reverse('logout')}" role="menuitem" class="dropdown-menuitem">${_("Sign Out")}</a></li>
</ul>
</div>
</li> </li>
</ol> </ol>
% endif % endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment