1/** 2 * Adds events to interact with the language switcher. 3 * @module LanguageSwitcher 4 * @author Martin Hubrich 5 */ 6 7'use strict'; 8 9// Self-written modules 10import { hideNavigation } from '../nav-main/nav-main.js'; 11 12// Cache all needed objects 13const body = document.querySelector('body'); 14const languageSwitcher = body.querySelector('#language-switcher'); 15const languageDropdownToggle = languageSwitcher !== null ? languageSwitcher.querySelector('[data-language-dropdown-toggle]') : undefined; 16const languageDropdown = languageSwitcher !== null ? languageSwitcher.querySelector('.language-switcher__dropdown') : undefined; 17const languageDropdownFirstEntry = languageDropdown !== undefined ? languageDropdown.querySelector('li:first-child a') : undefined; 18const languageDropdownLastEntry = languageDropdown !== undefined ? languageDropdown.querySelector('li:last-child a') : undefined; 19 20/** 21 * Initiates the module. 22 * @function init 23 * @public 24 */ 25export default function init() { 26 if (languageSwitcher !== null) { 27 _bindEvents(); 28 } 29} 30 31/** 32 * Binds all events to DOM objects. 33 * @function _bindEvents 34 * @private 35 */ 36function _bindEvents() { 37 languageDropdownToggle.addEventListener('click', _handleClickEvent, false); 38 39 window.addEventListener('resize:smart', () => { 40 closeDropdown(); 41 }); 42 43 // Closes the dropdown if the user clicked outside the language switcher 44 body.addEventListener('click', (event) => { 45 if (!Object.is(event.target, languageSwitcher) 46 && !event.target.closest('#language-switcher')) { 47 closeDropdown(); 48 } 49 }, false); 50} 51 52/** 53 * Handle events which are received by clicking the current target. 54 * @function _handleClickEvent 55 * @param {Object} event - default event object 56 * @private 57 */ 58function _handleClickEvent(event) { 59 _toggleDropdownVisibility(event.currentTarget); 60} 61 62/** 63 * Handle events which are received by pressing a keyboard key. 64 * @function _handleKeyEvent 65 * @param {Object} event - default event object 66 * @private 67 */ 68function _handleKeyEvent(event) { 69 let key = event.charCode ? event.charCode : event.keyCode ? event.keyCode : 0; 70 71 switch (key) { 72 case 9: // Tab 73 if (event.shiftKey) { // Check if shift is pressed 74 if (event.target === languageDropdownFirstEntry) { 75 languageDropdownLastEntry.focus(); 76 event.preventDefault(); 77 } 78 } else { 79 if (event.target === languageDropdownLastEntry) { 80 languageDropdownFirstEntry.focus(); 81 event.preventDefault(); 82 } 83 } 84 break; 85 case 27: // ESC 86 closeDropdown(); 87 languageDropdownToggle.focus(); 88 break; 89 } 90} 91 92/** 93 * Opens the language dropdown if it's closed and reversed. 94 * @function _toggleDropdownVisibility 95 * @param {Element} toggle - the clicked dropdown header 96 * @private 97 */ 98function _toggleDropdownVisibility(toggle) { 99 if (toggle.getAttribute('aria-expanded') === 'false') { 100 hideNavigation(); 101 _openDropdown(); 102 } else { 103 closeDropdown(); 104 } 105} 106 107/** 108 * Closes the language dropdown. 109 * @function closeDropdown 110 * @public 111 */ 112export function closeDropdown() { 113 if (languageSwitcher !== null) { 114 languageDropdownToggle.setAttribute('aria-expanded', false); 115 116 window.removeEventListener('keydown', _handleKeyEvent); 117 } 118} 119 120/** 121 * Opens the language dropdown. 122 * @function _openDropdown 123 * @private 124 */ 125function _openDropdown() { 126 languageDropdownToggle.setAttribute('aria-expanded', true); 127 128 // We need a small delay before setting the new focus because the element 129 // isn't visible yet. Therefore it can't be focused. 130 setTimeout(() => { 131 languageDropdownFirstEntry.focus(); 132 }, 100); 133 134 window.addEventListener('keydown', _handleKeyEvent, false); 135}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.