1/** 2 * Search popup focus return (Divi 5 header search) 3 * 4 * When the menu search overlay (.et_pb_menu__search-container) is opened via 5 * the search button and then closed via the close button (or any other 6 * means), Divi drops focus to <body>. For keyboard users that means losing 7 * their place in the navigation. Per WCAG 2.4.3 (Focus Order), focus should 8 * return to the trigger element that opened the overlay. 9 * 10 * Approach: cache the most-recently-activated search-button. When a 11 * MutationObserver sees the container's visibility class change from 12 * visible to hidden, restore focus to that cached trigger. 13 */ 14(function () { 15 const TRIGGER_SELECTOR = '.et_pb_menu__search-button'; 16 const CONTAINER_SELECTOR = '.et_pb_menu__search-container'; 17 const VISIBLE_CLASS = 'et_pb_menu__search-container--visible'; 18 19 let lastTrigger = null; 20 21 function rememberTrigger(e) { 22 const trigger = e.target.closest(TRIGGER_SELECTOR); 23 if (trigger) lastTrigger = trigger; 24 } 25 26 function watchContainer(container) { 27 let wasVisible = container.classList.contains(VISIBLE_CLASS); 28 const observer = new MutationObserver(function () { 29 const isVisible = container.classList.contains(VISIBLE_CLASS); 30 if (wasVisible && !isVisible && lastTrigger) { 31 // Defer one frame so Divi finishes any focus changes before we restore. 32 requestAnimationFrame(function () { 33 lastTrigger.focus(); 34 }); 35 } 36 wasVisible = isVisible; 37 }); 38 observer.observe(container, { attributes: true, attributeFilter: ['class'] }); 39 } 40 41 function init() { 42 document.addEventListener('click', rememberTrigger); 43 document.addEventListener('keydown', function (e) { 44 if (e.key === 'Enter' || e.key === ' ') rememberTrigger(e); 45 }); 46 document.querySelectorAll(CONTAINER_SELECTOR).forEach(watchContainer); 47 } 48 49 if (document.readyState === 'loading') { 50 document.addEventListener('DOMContentLoaded', init); 51 } else { 52 init(); 53 } 54})();
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.