1jQuery(function ($) { 2 console.log('JS initialized.'); 3 4 function mainNav() { 5 let trigger, siteNav; 6 trigger = $('#nav-trigger'); 7 siteNav = $('#site-navigation'); 8 $(trigger).on( 'click', function() { 9 let condition = $(this).attr('aria-expanded'); 10 if ( condition == 'true' ) { 11 $(this).attr('aria-expanded', 'false'); 12 $(siteNav).removeClass('expanded'); 13 } else { 14 $(this).attr('aria-expanded', 'true'); 15 $(siteNav).addClass('expanded'); 16 } 17 }); 18 } 19 20 function subNavs() { 21 let trigger; 22 trigger = $('#secondary-navigation button.menu-item'); 23 $(trigger).on('click', function() { 24 let condition, allNavs, thisNav; 25 condition = $(this).attr('aria-expanded'); 26 allNavs = $('#secondary-navigation ul.sub-menu'); 27 thisNav = $(this).siblings('ul.sub-menu'); 28 29 if (condition == 'true') { 30 $(trigger).attr('aria-expanded', 'false'); 31 $(allNavs).removeClass('expanded'); 32 } else { 33 $(trigger).attr('aria-expanded', 'false'); 34 $(allNavs).removeClass('expanded'); 35 $(this).attr('aria-expanded', 'true'); 36 $(thisNav).addClass('expanded'); 37 // listenForClick(thisNav); 38 } 39 }); 40 } 41 42 function videoDialog() { 43 if (typeof HTMLDialogElement === "undefined") { 44 // Optional: load a <dialog> polyfill or fall back to a non-dialog modal. 45 return; 46 } 47 48 var $dialog = $("#video-modal"); 49 if (!$dialog.length) return; 50 51 /** @type {HTMLDialogElement} */ 52 var dialogEl = $dialog.get(0); 53 54 var lastActiveElement = null; 55 56 var focusableSelector = [ 57 "a[href]", 58 "area[href]", 59 "button:not([disabled])", 60 "input:not([disabled]):not([type='hidden'])", 61 "select:not([disabled])", 62 "textarea:not([disabled])", 63 "[tabindex]:not([tabindex='-1'])", 64 ].join(","); 65 66 function getFocusable() { 67 // Filter out elements that are not actually visible (rough-but-practical) 68 return $dialog 69 .find(focusableSelector) 70 .filter(function () { 71 var $el = $(this); 72 return $el.is(":visible") && !$el.is("[inert]"); 73 }) 74 .toArray(); 75 } 76 77 function setInitialFocus() { 78 var $autofocus = $dialog.find("[autofocus]").first(); 79 if ($autofocus.length) { 80 $autofocus.trigger("focus"); 81 return; 82 } 83 84 var focusable = getFocusable(); 85 if (focusable.length) { 86 focusable[0].focus(); 87 return; 88 } 89 90 // Last resort
91 dialogEl.focus(); 92 } 93 94 function lockScroll(lock) { 95 $("html").css("overflow", lock ? "hidden" : ""); 96 } 97 98 function openDialog() { 99 lastActiveElement = document.activeElement; 100 101 // showModal() is key for proper modality + top-layer behavior 102 dialogEl.showModal(); 103 104 lockScroll(true); 105 setInitialFocus(); 106 } 107 108 function closeDialog() { 109 if (dialogEl.open) dialogEl.close("dismissed"); 110 } 111 112 // Open triggers: <button data-dialog-open="video-modal"> 113 $(document).on("click", "[data-dialog-open]", function (e) { 114 var targetId = $(this).attr("data-dialog-open"); 115 if (targetId !== dialogEl.id) return; 116 openDialog(); 117 }); 118 119 // Optional: close on backdrop click 120 $dialog.on("click", function (e) { 121 // If click is outside the dialog box (on the backdrop area), close 122 var rect = dialogEl.getBoundingClientRect(); 123 var x = e.clientX; 124 var y = e.clientY; 125 126 var clickInside = 127 x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom; 128 129 if (!clickInside) closeDialog(); 130 }); 131
132 // Focus trap: keep Tab/Shift+Tab inside 133 $dialog.on("keydown", function (e) { 134 if (e.key !== "Tab" && e.keyCode !== 9) return; 135 136 var focusable = getFocusable(); 137 if (!focusable.length) return; 138 139 var first = focusable[0]; 140 var last = focusable[focusable.length - 1]; 141 142 if (e.shiftKey && document.activeElement === first) { 143 e.preventDefault(); 144 last.focus(); 145 } else if (!e.shiftKey && document.activeElement === last) { 146 e.preventDefault(); 147 first.focus(); 148 } 149 }); 150 151 // Escape key: <dialog> handles it; we just ensure cleanup happens in "close" 152 $dialog.on("cancel", function () { 153 // Donât preventDefault(); allow Esc to close. 154 }); 155 156 // Cleanup + restore focus 157 $dialog.on("close", function () { 158 lockScroll(false); 159 160 if (lastActiveElement && typeof lastActiveElement.focus === "function") { 161 lastActiveElement.focus(); 162 } 163 }); 164 165 166 $(document).on("click", "#video-modal .dialog-close", function (e) { 167 e.preventDefault(); 168 var dialogEl = $("#video-modal").get(0); 169 if (dialogEl && dialogEl.open) dialogEl.close("dismissed"); 170 }); 171 } 172 173 function splideInit() { 174 const splide = new Splide( '.splide', { 175 type : 'loop', 176 perPage: 1, 177 arrows : false, 178 } ); 179 180 splide.on( 'pagination:mounted', function ( data ) { 181 // You can add your class to the UL element 182 data.list.classList.add( 'splide__pagination--spotlight' ); 183 184 // `items` contains all dot items 185 data.items.forEach( function ( item ) { 186 var slideNum, slideString, slideID, slideH3, slideTitle; 187 slideNum = item.page + 1; 188 if (slideNum < 10) { 189 slideString = slideNum.toString(); 190 slideNum = slideString.padStart(2, "0"); 191 } 192 slideID = "#splide01-slide"+slideNum; 193 slideH3 = slideID + " h3"; 194 slideTitle = $(slideH3).text(); 195 item.button.textContent = String( slideTitle ); 196 } ); 197 } ); 198 199 splide.mount(); 200 } 201 202 function main() { 203 mainNav(); 204 subNavs(); 205 videoDialog(); 206 splideInit(); 207 } 208 209 $(document).ready(function(){ 210 console.log('main function running.'); 211 main(); 212 }); 213});
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.