Files
edx-platform/lms/static/js/header/header.js
Syed Ali Abbas Zaidi d7053a6783 fix: eslint autofixable issues (#32181)
* fix: eslint operator-linebreak issue

* fix: eslint quotes issue

* fix: react jsx indent and props issues

* fix: eslint trailing spaces issues

* fix: eslint line around directives issue

* fix: eslint semi rule

* fix: eslint newline per chain rule

* fix: eslint space infix ops rule

* fix: eslint space-in-parens issue

* fix: eslint space before function paren issue

* fix: eslint space before blocks issue

* fix: eslint arrow body style issue

* fix: eslint dot-location issue

* fix: eslint quotes issue

* fix: eslint quote props issue

* fix: eslint operator assignment issue

* fix: eslint new line after import issue

* fix: indent issues

* fix: operator assignment issue

* fix: all autofixable eslint issues

* fix: all react related fixable issues

* fix: autofixable eslint issues

* chore: remove all template literals

* fix: remaining autofixable issues

* fix: failing js test
2023-05-18 11:03:59 +05:00

185 lines
7.7 KiB
JavaScript

/**
* Ensuring collapsible and accessible components on multiple
* screen sizes for the responsive lms header.
*/
function createMobileMenu() {
/**
* Dynamically create a mobile menu from all specified mobile links
* on the page.
*/
'use strict';
$('.mobile-nav-item').each(function() {
var mobileNavItem = $(this).clone().addClass('mobile-nav-link');
mobileNavItem.removeAttr('role');
mobileNavItem.find('a').attr('role', 'menuitem');
// xss-lint: disable=javascript-jquery-append
$('.mobile-menu').append(mobileNavItem);
});
}
$(document).ready(function() {
'use strict';
var $hamburgerMenu;
var $mobileMenu;
// Toggling visibility for the user dropdown
$('.global-header .toggle-user-dropdown, .global-header .toggle-user-dropdown span').click(function(e) {
var $dropdownMenu = $('.global-header .nav-item .dropdown-user-menu');
var $userDropdown = $('.global-header .toggle-user-dropdown');
if ($dropdownMenu.is(':visible')) {
$dropdownMenu.addClass('hidden');
$userDropdown.attr('aria-expanded', 'false');
} else {
$dropdownMenu.removeClass('hidden');
$dropdownMenu.find('.dropdown-item')[0].focus();
$userDropdown.attr('aria-expanded', 'true');
}
$('.global-header .toggle-user-dropdown').toggleClass('open');
e.stopPropagation();
});
// Hide user dropdown on click away
if ($('.global-header .nav-item .dropdown-user-menu').length) {
$(window).click(function(e) {
var $dropdownMenu = $('.global-header .nav-item .dropdown-user-menu');
var $userDropdown = $('.global-header .toggle-user-dropdown');
if ($userDropdown.is(':visible') && !$(e.target).is('.dropdown-item, .toggle-user-dropdown')) {
$dropdownMenu.addClass('hidden');
$userDropdown.attr('aria-expanded', 'false');
}
});
}
// Toggling menu visibility with the hamburger menu
$('.global-header .hamburger-menu').click(function() {
$hamburgerMenu = $('.global-header .hamburger-menu');
$mobileMenu = $('.mobile-menu');
if ($mobileMenu.is(':visible')) {
$mobileMenu.addClass('hidden');
$hamburgerMenu.attr('aria-expanded', 'false');
} else {
$mobileMenu.removeClass('hidden');
$hamburgerMenu.attr('aria-expanded', 'true');
}
$hamburgerMenu.toggleClass('open');
});
// Hide hamburger menu if no nav items (sign in and register pages)
if ($('.mobile-nav-item').size() === 0) {
$('.global-header .hamburger-menu').addClass('hidden');
}
createMobileMenu();
});
// Accessibility keyboard controls for user dropdown and mobile menu
$('.mobile-menu, .global-header').on('keydown', function(e) {
'use strict';
var isNext,
nextLink,
loopFirst,
loopLast,
$curTarget = $(e.target),
isLastItem = $curTarget.parent().is(':last-child'),
isToggle = $curTarget.hasClass('toggle-user-dropdown'),
isHamburgerMenu = $curTarget.hasClass('hamburger-menu'),
isMobileOption = $curTarget.parent().hasClass('mobile-nav-link'),
isDropdownOption = !isMobileOption && $curTarget.parent().hasClass('dropdown-item'),
$userDropdown = $('.global-header .user-dropdown'),
$hamburgerMenu = $('.global-header .hamburger-menu'),
$toggleUserDropdown = $('.global-header .toggle-user-dropdown');
// Open or close relevant menu on enter or space click and focus on first element.
if ((e.key === 'Enter' || e.key === 'Space') && (isToggle || isHamburgerMenu)) {
e.preventDefault();
e.stopPropagation();
$curTarget.click();
if (isHamburgerMenu) {
if ($('.mobile-menu').is(':visible')) {
$hamburgerMenu.attr('aria-expanded', true);
$('.mobile-menu .mobile-nav-link a').first().focus();
} else {
$hamburgerMenu.attr('aria-expanded', false);
}
} else if (isToggle) {
if ($('.global-header .nav-item .dropdown-user-menu').is(':visible')) {
$userDropdown.attr('aria-expanded', 'true');
$('.global-header .dropdown-item a:first').focus();
} else {
$userDropdown.attr('aria-expanded', false);
}
}
}
// Enable arrow functionality within the menu.
if ((e.key === 'ArrowUp' || e.key === 'ArrowDown') && (isDropdownOption || isMobileOption
|| (isHamburgerMenu && $hamburgerMenu.hasClass('open')) || isToggle && $toggleUserDropdown.hasClass('open'))) {
isNext = e.key === 'ArrowDown';
if (isNext && !isHamburgerMenu && !isToggle && isLastItem) {
// Loop to the start from the final element
nextLink = isDropdownOption ? $toggleUserDropdown : $hamburgerMenu;
} else if (!isNext && (isHamburgerMenu || isToggle)) {
// Loop to the end when up arrow pressed from menu icon
nextLink = isHamburgerMenu ? $('.mobile-menu .mobile-nav-link a').last()
: $('.global-header .dropdown-user-menu .dropdown-nav-item').last().find('a');
} else if (isNext && (isHamburgerMenu || isToggle)) {
// Loop to the first element from the menu icon
nextLink = isHamburgerMenu ? $('.mobile-menu .mobile-nav-link a').first()
: $('.global-header .dropdown-user-menu .dropdown-nav-item').first().find('a');
} else {
// Loop up to the menu icon if first element in menu
if (!isNext && $curTarget.parent().is(':first-child') && !isHamburgerMenu && !isToggle) {
nextLink = isDropdownOption ? $toggleUserDropdown : $hamburgerMenu;
} else {
nextLink = isNext
? $curTarget.parent().next().find('a') // eslint-disable-line newline-per-chained-call
: $curTarget.parent().prev().find('a'); // eslint-disable-line newline-per-chained-call
}
}
nextLink.focus();
// Don't let the screen scroll on navigation
e.preventDefault();
e.stopPropagation();
}
// Escape clears out of the menu
if (e.key === 'Escape' && (isDropdownOption || isHamburgerMenu || isMobileOption || isToggle)) {
if (isDropdownOption || isToggle) {
$('.global-header .nav-item .dropdown-user-menu').addClass('hidden');
$toggleUserDropdown.focus()
.attr('aria-expanded', 'false');
$('.global-header .toggle-user-dropdown').removeClass('open');
} else {
$('.mobile-menu').addClass('hidden');
$hamburgerMenu.focus()
.attr('aria-expanded', 'false')
.removeClass('open');
}
}
// Loop when tabbing and using arrows
if ((e.key === 'Tab') && ((isDropdownOption && isLastItem) || (isMobileOption && isLastItem) || (isHamburgerMenu
&& $hamburgerMenu.hasClass('open')) || (isToggle && $toggleUserDropdown.hasClass('open')))) {
nextLink = null;
loopFirst = isLastItem && !e.shiftKey && !isHamburgerMenu && !isToggle;
loopLast = (isHamburgerMenu || isToggle) && e.shiftKey;
if (!(loopFirst || loopLast)) {
return;
}
e.preventDefault();
if (isDropdownOption || isToggle) {
nextLink = loopFirst ? $toggleUserDropdown
: $('.global-header .dropdown-user-menu .dropdown-nav-item a').last();
} else {
nextLink = loopFirst ? $hamburgerMenu : $('.mobile-menu .mobile-nav-link a').last();
}
nextLink.focus();
}
});