1(function($, Proud) { 2 3 // Proudnav 4 var proudNav = (function() { 5 6 var layerOpen = { 7 menu: false, 8 search: false, 9 answers: false, 10 }, 11 layerClasses = { 12 'menu': 'menu-nav-open', 13 'search': 'search-active', 14 'answers': 'active-311' 15 }, 16 $body, 17 self = {}; 18 19 // Closes overlays + menus 20 // localLayers = ['menu', 'search'] 21 self.closeLayers = function(localLayers, callback) { 22 // Default is all 23 localLayers = localLayers || lodash.keys(layerOpen); 24 var classes = []; 25 lodash.map(localLayers, function(layer) { 26 classes.push(layerClasses[layer]); 27 layerOpen[layer] = false; 28 }); 29 // Remove 30 $body.removeClass(classes.join(' ')); 31 if(callback) { 32 callback(); 33 } 34 }; 35 36 // Closes overlays + menus 37 self.openLayer = function(layer, callback) { 38 setTimeout(function() { 39 $body.addClass(layerClasses[layer]); 40 layerOpen[layer] = true; 41 $body.trigger('scroll'); 42 if(callback) { 43 callback(); 44 } 45 }, 50); 46 }; 47 48 self.toggleMenu = function() { 49 // Just close everything 50 if(layerOpen.menu) { 51 self.closeLayers(); 52 return; 53 } 54 else { 55 self.closeLayers(['answers', 'search']); 56 self.openLayer('menu'); 57 } 58 }; 59 60 self.toggleOverlay = function(item, callback) { 61 var thisLayer, otherLayer; 62 switch(item) { 63 case 'answers': 64 case 'payments': 65 case 'report': 66 case 'status': 67 thisLayer = 'answers'; 68 otherLayer = 'search'; 69 break; 70 71 case 'search': 72 thisLayer = 'search'; 73 otherLayer = 'answers'; 74 break; 75 } 76 77 // Close all 78 if(layerOpen[thisLayer]) { 79 self.closeLayers(null, callback); 80 } 81 else { 82 // Close others, open ours 83 self.closeLayers([otherLayer, 'menu'], callback); 84 self.openLayer(thisLayer, callback); 85 } 86 }; 87 88 self.triggerOverlay = function(data, hash, classOverride) { 89 if(classOverride) { 90 layerClasses[data] = classOverride; 91 } 92 93 $body.trigger({ 94 type: "proudNavClick", 95 event: data, 96 hash: hash, 97 callback: function(open, scrollId, scrollOffset, forceClose, callback) { 98 // Scrollto id 99 if(scrollId) { 100 var $scroll = $("#" + scrollId), 101 scrollOffset = scrollOffset || 0, 102 offset = $body.hasClass('admin-bar') ? 170 : 100; 103 if($scroll.length) { 104 $('html, body').animate({ 105 scrollTop: $scroll.offset().top - (offset + scrollOffset) 106 }, 200); 107 } 108 } 109 // Oper layer 110 if(open) { 111 self.toggleOverlay(data, callback); 112 } 113 // Force close layers 114 if(forceClose) { 115 self.closeLayers(forceClose, callback); 116 } 117 } 118 }); 119 }; 120 121 // Align the fixed hamburger with the visible logo row. 122 // 123 // On topbar-enabled sites the action toolbar lives inside the topbar, whose 124 // height changes with viewport width: the official statement and action 125 // icons sit on one row when wide and wrap to two rows when narrow. The 126 // hamburger is position:fixed, so a static CSS top can't track that. Measure 127 // the logo row (.navbar-header-region) and centre the button on it. Using 128 // the rect also accounts for the admin bar automatically. Non-topbar sites 129 // keep their CSS offset untouched. 130 self.positionMenuButton = function() { 131 // Run for both topbar layouts: the full topbar (proud-navbar-topbar-active) 132 // and the default mobile-only top bar (proud-navbar-topbar-mobile-only-active). 133 // The latter relied on static CSS offsets that ignored the WordPress admin 134 // bar, so the fixed button drifted off the logo row when logged in. 135 if (!$body || 136 (!$body.hasClass('proud-navbar-topbar-active') && 137 !$body.hasClass('proud-navbar-topbar-mobile-only-active'))) { 138 return; 139 } 140 var $button = $('#menu-button'); 141 var region = document.querySelector('.navbar-header-region'); 142 if (!$button.length || !region) { 143 return; 144 } 145 // Only when the mobile hamburger is showing; clear our override otherwise 146 // so the desktop layout is unaffected. 147 if ($button.css('display') === 'none') { 148 $button.css('top', ''); 149 return; 150 } 151 var r = region.getBoundingClientRect(); 152 var top = r.top + window.pageYOffset + (r.height - $button.outerHeight()) / 2; 153 $button.css('top', Math.round(top) + 'px'); 154 }; 155 156 $(document).ready(function() { 157 $body = $('body'); 158 159 // Listen for esc key 160 $body.keydown(function(e) { //keypress did not work with ESC; 161 if (e.which == '27') { 162 var closing = true; 163 lodash.map(layerOpen, function(val) { 164 if(val && closing) { 165 self.closeLayers(); 166 closing = false;
167 } 168 }); 169 } 170 }); 171 172 self.positionMenuButton(); 173 $(window).on( 174 'resize.proudNavbarButton orientationchange.proudNavbarButton load.proudNavbarButton', 175 function() { self.positionMenuButton(); } 176 ); 177 }) 178 179 return self; 180 })(); 181 182 Proud.proudNav = proudNav; 183 184 Proud.behaviors.proudNavbar = { attach: function(context, settings) { 185 186 var $body = $('body'); 187 188 // Click top buttons 189 $('[data-proud-navbar]').once('proud-navbar', function() { 190 var $self = $(this); 191 $self.click(function(e) { 192 // Allow for link override 193 if(!$self.data('click-external')) { 194 e.preventDefault(); 195 var data = $self.data('proud-navbar'); 196 197 if(data) { 198 proudNav.triggerOverlay(data, $self.data('proud-navbar-hash')); 199 } 200 } 201 }); 202 }); 203 204 // Focus out timer 205 var menuItemTimer = null; 206 207 // mobile menu open 208 $('#menu-button').once('proud-navbar', function() { 209 $(this).click(function(e) { 210 e.preventDefault(); 211 if (menuItemTimer) { 212 clearTimeout(menuItemTimer); 213 } 214 if(!$body.hasClass('menu-nav-open')) { 215 $('#main-menu').children(":first").children().focus(); 216 } 217 proudNav.toggleMenu(); 218 }); 219 }); 220 221 // On main menu focus (tabbing) open up menu 222 $('#main-menu').once('proud-main-menu', function() { 223 $('a', $(this)).on('focusin', function () { 224 clearTimeout(menuItemTimer); 225 proudNav.openLayer('menu'); 226 }).on('focusout', function () { 227 menuItemTimer = setTimeout(function() { 228 proudNav.closeLayers(['menu']); 229 }, 100); 230 }); 231 }); 232 233 // close overlay 234 $('#overlay-311-close, #overlay-search-close').once('proud-navbar', function() { 235 $(this).click(function(e) { 236 e.preventDefault(); 237 proudNav.closeLayers(); 238 }); 239 }); 240 241 }}; 242})(jQuery, Proud); 243
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.