1$(function() { 2 var isMobileEscaping = false; 3 4 // ========================================================================== 5 // 0. DYNAMIC HAMBURGER TAG TRANSFORMATION ENGINE (GLOBAL COMPLIANCE FIX) 6 // ========================================================================== 7 function transformHamburgerToTrueButton() { 8 var $hamburger = $('#wsnavtoggle'); 9 10 // If it is currently an anchor tag (<a>), swap it to a true <button> 11 if ($hamburger.length > 0 && $hamburger.is('a')) { 12 var $trueButton = $('<button>', { 13 'id': $hamburger.attr('id'), 14 'class': $hamburger.attr('class'), 15 'aria-expanded': $hamburger.attr('aria-expanded') || 'false', 16 'type': 'button' 17 }); 18 19 // Move the inner structural contents (like the <span> elements) safely over 20 $trueButton.html($hamburger.html()); 21 22 // Swap out the nodes inside the live DOM tree framework 23 $hamburger.replaceWith($trueButton); 24 } 25 } 26 27 // Run transformation loop instantly on file compilation entry phase 28 transformHamburgerToTrueButton(); 29 30 31 // ========================================================================== 32 // 1. HAMBURGER TOGGLE & OVERLAY MANAGEMENT 33 // ========================================================================== 34 $(document).off('click', '#wsnavtoggle').on('click', '#wsnavtoggle', function(e) { 35 e.preventDefault(); 36 $('.wsmenucontainer').toggleClass('wsoffcanvasopener'); 37 var isOpen = $('.wsmenucontainer').hasClass('wsoffcanvasopener'); 38 $(this).attr('aria-expanded', isOpen ? 'true' : 'false'); 39 40 if (isOpen) { 41 setTimeout(function() { 42 $('#wsnavtoggle').focus(); 43 }, 150); 44 } else { 45 setTimeout(function() { 46 $('#wsnavtoggle').focus(); 47 initializeDynamicMobilePassThrough(); 48 }, 50); 49 } 50 }); 51 52 $(document).off('click', '.overlapblackbg').on('click', '.overlapblackbg', function() { 53 $('.wsmenucontainer').removeClass('wsoffcanvasopener'); 54 $('#wsnavtoggle').attr('aria-expanded', 'false').focus(); 55 }); 56 57 58 59 // ==========================================================================
60 // 2. ACCESSIBLE BUTTON INJECTIONS (FIXED POSITION BETWEEN LINK AND UL) 61 // ========================================================================== 62 $('.wsmenu-list > li').has('.wsmenu-submenu, .megamenu').each(function() { 63 var $li = $(this); 64 var $anchor = $li.find('> a'); 65 var labelText = $anchor.text().trim(); 66 67 if (!$li.find('> .wsmenu-click').length) { 68 $('<button class="wsmenu-click" type="button" aria-expanded="false" aria-label="More ' + labelText + '"><i class="wsmenu-arrow fa fa-angle-down"></i></button>') 69 .insertAfter($anchor); 70 } 71 }); 72 73 $('.wsmenu-list > li > ul > li').has('.wsmenu-submenu-sub, .wsmenu-submenu-sub-sub').each(function() { 74 var $li = $(this); 75 var $anchor = $li.find('> a'); 76 var labelText = $anchor.text().trim(); 77 78 if (!$li.find('> .wsmenu-click02').length) { 79 $('<button class="wsmenu-click02" type="button" aria-expanded="false" aria-label="More ' + labelText + '"><i class="wsmenu-arrow fa fa-angle-down"></i></button>') 80 .insertAfter($anchor); 81 } 82 }); 83 84 // ========================================================================== 85 // 3. LEVEL 1 TOGGLE CONTROLLERS (CLEAN SLIDE INTERACTION) 86 // ========================================================================== 87 $('.wsmenu-click').off('click').click(function(e) { 88 e.preventDefault(); 89 e.stopPropagation(); 90 91 var $button = $(this); 92 var $parentLi = $button.closest('li'); 93 var $dropdownMenu = $parentLi.find('> .wsmenu-submenu, > .megamenu'); 94 var isCurrentlyOpen = $button.attr('aria-expanded') === 'true'; 95 96 if (!isMobileEscaping) { 97 $('.wsmenu-click').not($button).attr('aria-expanded', 'false').removeClass('ws-activearrow'); 98 $('.wsmenu-submenu, .megamenu').not($dropdownMenu).slideUp('slow'); 99 $('.wsmenu-list > li').not($parentLi).removeClass('sfHover'); 100 } 101 102 if (isCurrentlyOpen) { 103 $button.attr('aria-expanded', 'false').removeClass('ws-activearrow'); 104 $dropdownMenu.slideUp('slow'); 105 $parentLi.removeClass('sfHover'); 106 } else { 107 $button.attr('aria-expanded', 'true').addClass('ws-activearrow'); 108 $dropdownMenu.slideDown('slow'); 109 $parentLi.addClass('sfHover'); 110 } 111 }); 112 113 // ========================================================================== 114 // 4. LEVEL 2 TOGGLE CONTROLLERS (CLEAN SLIDE INTERACTION) 115 // ========================================================================== 116 $('.wsmenu-click02').off('click').click(function(e) { 117 e.preventDefault(); 118 e.stopPropagation(); 119 120 var $button = $(this); 121 var $parentLi = $button.closest('li'); 122 var $subChildUl = $parentLi.find('> .wsmenu-submenu-sub, > .wsmenu-submenu-sub-sub'); 123 var isCurrentlyOpen = $button.attr('aria-expanded') === 'true'; 124 125 if (isCurrentlyOpen) { 126 $button.attr('aria-expanded', 'false').children('.wsmenu-arrow').removeClass('wsmenu-rotate'); 127 $subChildUl.slideUp('slow'); 128 } else { 129 $button.attr('aria-expanded', 'true').children('.wsmenu-arrow').addClass('wsmenu-rotate'); 130 $subChildUl.slideDown('slow'); 131 } 132 }); 133 134 135 136 137 // ========================================================================== 138 // 5. UNIFIED MOBILE ESCAPE CONTROLLER LOGIC (FIXED SINGLE-LEVEL BUTTON FOCUS) 139 // ========================================================================== 140 $('.wsmenu-list').off('keydown').on('keydown', function(event) { 141 if (window.innerWidth < 768 && (event.key === 'Escape' || event.key === 'Esc')) { 142 var $activeElement = $(document.activeElement); 143 144 // ------------------------------------------------------------------ 145 // TIER 1: Focus is deep inside an Inner Level Submenu (e.g., "The Board") 146 // ------------------------------------------------------------------ 147 if ($activeElement.closest('.wsmenu-submenu-sub, .sub_child2, .wsmenu-submenu-sub-sub').length > 0) { 148 event.preventDefault(); 149 event.stopPropagation(); 150 151 var $parentFolderLi = $activeElement.closest('.has-accessible-submenu'); 152 var $parentFolderBtn = $parentFolderLi.find('> button.wsmenu-click02, > .wsmenu-click02'); 153 154 if ($parentFolderBtn.attr('aria-expanded') === 'true') { 155 isMobileEscaping = true; 156 157 $parentFolderBtn.trigger('click'); 158 $parentFolderBtn.attr('aria-expanded', 'false'); 159 $parentFolderBtn.children('.wsmenu-arrow').removeClass('wsmenu-rotate'); 160 161 // Focus moves onto the "About SEBI" toggle button item row 162 $parentFolderBtn.focus(); 163 164 setTimeout(function() { 165 isMobileEscaping = false; 166 }, 400); 167 } 168 return false; 169 } 170 171 // ------------------------------------------------------------------ 172 // TIER 2: Focus is on the Main Submenu folder level (e.g., Single-Level Dropdowns) 173 // ------------------------------------------------------------------ 174 if ($activeElement.closest('.wsmenu-submenu, .megamenu').length > 0) { 175 event.preventDefault(); 176 event.stopPropagation(); 177 178 var $rootLi = $activeElement.closest('.wsmenu-list > li, .sf-menu > li'); 179 var $rootToggleBtn = $rootLi.find('> button.wsmenu-click, > .wsmenu-click'); 180 181 if ($rootToggleBtn.attr('aria-expanded') === 'true') { 182 isMobileEscaping = true; 183 184 $rootToggleBtn.trigger('click'); 185 $rootToggleBtn.attr('aria-expanded', 'false'); 186 $rootToggleBtn.removeClass('ws-activearrow'); 187 188 // Move focus directly and reliably back to the toggle button 189 $rootToggleBtn.focus(); 190 191 setTimeout(function() { 192 isMobileEscaping = false; 193 }, 400); 194 } 195 return false; 196 } 197 } 198 });
199 200 // ========================================================================== 201 // 6. MOBILE NAVIGATION ARIA KEYBOARD FOCUS TRAP CONFIGURATION (STABILIZED) 202 // ========================================================================== 203 $(document).off('keydown.focustrap').on('keydown.focustrap', function(event) { 204 if (window.innerWidth < 768 && $('.wsmenucontainer').hasClass('wsoffcanvasopener')) { 205 206 if (event.key === 'Tab' || event.keyCode === 9) { 207 var $menuContainer = $('.wsmenu, .wsmenu-list'); 208 209 // Get all interior menu links and active visible toggle arrows 210 var $focusableElements = $menuContainer.find('a[href], button.wsmenu-click, button.wsmenu-click02').filter(':visible'); 211 var $closeToggleBtn = $('#wsnavtoggle').filter(':visible'); 212 213 var elementsArray = []; 214 215 // Establish close button wrapper coordinates at position 0 216 if ($closeToggleBtn.length > 0) { 217 elementsArray.push($closeToggleBtn[0]); 218 } 219 220 $focusableElements.each(function() { 221 elementsArray.push(this); 222 }); 223 224 if (elementsArray.length === 0) return; 225 226 var firstBoundary = elementsArray[0]; 227 var lastBoundary = elementsArray[elementsArray.length - 1]; 228 229 // Backward Trap Cycle (Shift + Tab) 230 if (event.shiftKey) { 231 if (document.activeElement === firstBoundary) { 232 event.preventDefault(); 233 $(lastBoundary).focus(); 234 } 235 } 236 // Forward Trap Cycle (Tab) 237 else { 238 if (document.activeElement === lastBoundary) { 239 event.preventDefault(); 240 $(firstBoundary).focus(); 241 } 242 } 243 } 244 } 245 }); 246 247 248 // ========================================================================== 249 // 7. RESPONSIVE ARIA-HIDDEN SWAPPER ENGINE (DESKTOP VS MOBILE TOGGLES) 250 // ========================================================================== 251 function syncResponsiveAriaStates() { 252 var isMobile = window.innerWidth < 768; 253 254 if (isMobile) { 255 // Mobile View Settings: 256 // 1. Hide the desktop toggle buttons from screen readers entirely 257 $('.submenu-toggle, #sebi-btn').attr({ 258 'aria-hidden': 'true', 259 'tabindex': '-1' // Prevents accidental keyboard focus 260 }); 261 262 // 2. Expose mobile framework toggle arrows safely to screen readers 263 $('.wsmenu-click, .wsmenu-click02').attr({ 264 'aria-hidden': 'false', 265 'tabindex': '0' 266 }); 267 } else { 268 // Desktop View Settings: 269 // 1. Expose desktop specific buttons back to standard access matrices 270 $('.submenu-toggle, #sebi-btn').attr({ 271 'aria-hidden': 'false', 272 'tabindex': '0' 273 }); 274 275 // 2. Hide mobile click containers entirely on desktop monitors 276 $('.wsmenu-click, .wsmenu-click02').attr({ 277 'aria-hidden': 'true', 278 'tabindex': '-1' 279 }); 280 } 281 } 282 283 // Run structural calculations instantly on page load initialization 284 syncResponsiveAriaStates(); 285 286 // Bind an event listener to keep properties aligned if a device is flipped or resized 287 $(window).on('resize', function() { 288 syncResponsiveAriaStates(); 289 }); 290 291 // ========================================================================== 292 // 8. GLOBAL MOBILE ACCESSIBILITY SKIP-TAB ENGINE (CORRECTED DELEGATION) 293 // ========================================================================== 294 function setInitialMobileFocus() { 295 if (window.innerWidth < 768) { 296 // Find the link containing the Azadi ka Amrit Mahotsav image asset target 297 var $azadiLogoLink = $('a[title="Azadi ka Amrit Mahotsav"], a:has(img[src*="azadi-logo"])').first(); 298 299 if ($azadiLogoLink.length > 0) { 300 // Instantly force focus onto the image link on page load 301 $azadiLogoLink.focus(); 302 } 303 } 304 } 305 306 // Execute the focus redirection immediately on script execution lifecycle entry 307 setInitialMobileFocus(); 308 309});
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.