1(function() { 2 3 function initializeModals() { 4 const modalDialogs = document.querySelectorAll('[data-cmp-is="modal-dialog"]'); 5 modalDialogs.forEach((modalDialog) => { 6 7 function findFocusableElements() { 8 return Array.from(modalDialog.querySelectorAll(` 9 a[href], 10 area[href], 11 input:not([disabled]), 12 select:not([disabled]), 13 textarea:not([disabled]), 14 button:not([disabled]), 15 iframe, 16 object, 17 embed, 18 [contenteditable], 19 [tabindex]:not([tabindex="-1"]) 20 `)).filter((el) => 21 el.offsetParent !== null 22 && !el.hasAttribute('inert') 23 && !el.closest('[inert]') 24 && !el.hasAttribute('data-focus-trap-edge') 25 ); 26 } 27 28 const focusTrapEdges = modalDialog.querySelectorAll('[data-focus-trap-edge]'); 29 if (focusTrapEdges.length > 1) { 30 const focusTrapStart = focusTrapEdges[0]; 31 const focusTrapEnd = focusTrapEdges[focusTrapEdges.length - 1]; 32 33 focusTrapStart.addEventListener('focus', () => { 34 const lastFocusableElement = findFocusableElements().pop(); 35 lastFocusableElement?.focus(); 36 }); 37 38 focusTrapStart.addEventListener('keydown', (event) => { 39 if (event.key === 'Tab' && event.shiftKey) { 40 event.preventDefault(); 41 } 42 }); 43 44 focusTrapEnd.addEventListener('focus', () => { 45 const firstFocusableElement = findFocusableElements()[0]; 46 firstFocusableElement?.focus(); 47 }); 48 49 focusTrapEnd.addEventListener('keydown', (event) => { 50 if (event.key === 'Tab' && !event.shiftKey) { 51 event.preventDefault(); 52 } 53 }); 54 } 55 56 modalDialog.addEventListener('keydown', (event) => { 57 if (event.key === 'Escape') { 58 event.preventDefault(); 59 event.stopPropagation(); 60 modalDialog.close(); 61 } 62 }); 63 64 modalDialog.addEventListener('toggle', (event) => { 65 if (event?.newState === 'open') { 66 setTimeout(() => { 67 const focusTarget = modalDialog.querySelector('[data-modal-open-focus-target]'); 68 const focusableElements = findFocusableElements(); 69 if (focusableElements.includes(focusTarget)) { 70 focusTarget.focus(); 71 } else { 72 for (const element of focusableElements) { 73 if (element.closest('[data-modal-open-focus-target]')) { 74 element.focus(); 75 break; 76 } 77 } 78 } 79 }, 1); 80 } 81 }); 82 83 const backdrop = modalDialog.closest('.modal'); 84 let backdropMouseDownTarget = undefined; 85 backdrop?.addEventListener('pointerdown', (event) => { 86 backdropMouseDownTarget = event.target; 87 }); 88 backdrop?.addEventListener('pointerup', (event) => { 89 if (event.target === backdrop && backdropMouseDownTarget === backdrop) { 90 modalDialog.close(); 91 } 92 }); 93 }); 94 } 95 96 if (document.readyState === 'complete') { 97 initializeModals(); 98 } else { 99 document.addEventListener('DOMContentLoaded', initializeModals); 100 } 101})();
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.