1// $Id: navigation.js 39999 2026-05-18 09:46:14Z brendon $ 2 3//--- CSS navigation menu ------------------------------------- 4// Requires: inArray(), multipleClasses() 5 6var cssMenus = { 7 delay: 180, 8 timer: 100, 9 LIs: [], 10 ULs: [], 11 revertLIs: [], 12 revertULs: [], 13 streamLIs: [], 14 streamULs: [], 15 activeLI: null, 16 activeUL: null, 17 secondLevel: null, 18 headerOuterHeight: 0, 19 stickyHeaderSpacer: 0, 20 21 clearStreamLI: function () { 22 // remove "expanded" class from list items 23 for (var x = 0; x < this.streamLIs.length; x++) { 24 multipleClasses("remove", this.streamLIs[x], "expanded"); 25 } 26 27 this.streamLIs = []; 28 }, 29 30 hideStreamUL: function () { 31 // hide lists 32 for (var x = 0; x < this.streamULs.length; x++) { 33 if (typeof jQuery != 'undefined') { 34 $(this.streamULs[x]).slideUp(this.delay); 35 } else { 36 this.streamULs[x].style.display = "none"; 37 } 38 } 39 40 this.streamULs = []; 41 }, 42 43 showActive: function (obj, dropmenuID) { 44 // add "expanded" class to the active list item, set activeLI 45 multipleClasses("add", obj, "expanded"); 46 // shows expanded arrow onClick 47 $(".js ul.firstLevelWrapper li.expanded div.arrow").css('display','block'); 48 49 this.activeLI = obj; 50 51 // if list item not already in streamLIs, add to streamLIs 52 if (!inArray(this.activeLI, this.streamLIs)) { 53 this.streamLIs[this.streamLIs.length] = this.activeLI; 54 } 55 56 // if a submenu list exists and is not already active, then show submenu list 57 if ((dropmenuID != null) && (dropmenuID > "") && (dropmenuID != this.activeUL)) { 58 // show new list, set activeUL 59 if (typeof jQuery != 'undefined') { 60 $("#" + dropmenuID).slideDown(this.delay); 61 } else { 62 document.getElementById(dropmenuID).style.display = "block"; 63 } 64 this.activeUL = document.getElementById(dropmenuID); 65 66 // if list not already in streamULs and not firstLevel, add to streamULs 67 if (!inArray(this.activeUL, this.streamULs) && !multipleClasses("check", this.activeUL, "firstLevelWrapper")) { 68 this.streamULs[this.streamULs.length] = this.activeUL; 69 } 70 } 71 }, 72 73 dropit: function (obj, dropmenuID, displayMenu) { 74 // actions for list items 75 // issue: clicking outside span, doesnt scroll up 76 var checkActiveLI = (this.activeLI == obj); 77 if (this.streamLIs.length == 0) { 78 if (!checkActiveLI || displayMenu) { 79 cssMenus.hide(obj, false); 80 } 81 if (!displayMenu) { 82 cssMenus.showActive(obj, dropmenuID); 83 } 84 } else { 85 cssMenus.hide(obj, true); 86 if (!checkActiveLI) { 87 // cssMenus.showActive(obj, dropmenuID); 88 setTimeout(function() { cssMenus.showActive(obj, dropmenuID); }, this.timer); 89 } 90 } 91 }, 92 93 hide: function (obj, timeOut) { 94 // if list item is on firstLevelWrapper 95 if (multipleClasses("check", obj.parentNode, "firstLevelWrapper")) { 96 cssMenus.hideStreamUL(); 97 if (timeOut) { 98 // cssMenus.clearStreamLI(); 99 setTimeout(function() { cssMenus.clearStreamLI(); }, this.timer); 100 } else { 101 cssMenus.clearStreamLI(); 102 } 103 } 104 }, 105 106 init: function () { 107 // build obects of all unordered lists and list items in the navigation div 108 if (document.getElementById(arguments[0])) { 109 this.ULs = document.getElementById(arguments[0]).getElementsByTagName("ul"); 110 this.LIs = document.getElementById(arguments[0]).getElementsByTagName("li"); 111 112 // build array of active lists to revert to 113 for (var x = 0; x < this.ULs.length; x++) { 114 // if list class contains "expanded" and not "firstLevelWrapper" 115 if (multipleClasses("check", this.ULs[x], "expanded")) { 116 if (!multipleClasses("check", this.ULs[x], "firstLevelWrapper")) { 117 this.revertULs[this.revertULs.length] = this.ULs[x]; 118 this.streamULs[this.streamULs.length] = this.ULs[x]; 119 } 120 } 121 } 122 123 // set active list 124 //this.activeUL = this.revertULs[this.revertULs.length-1]; 125 126 // build array of active list items to revert to 127 for (var x = 0; x < this.LIs.length; x++) { 128 // if list item class contains "expanded" 129 if (multipleClasses("check", this.LIs[x], "expanded")) { 130 this.revertLIs[this.revertLIs.length] = this.LIs[x]; 131 this.streamLIs[this.streamLIs.length] = this.LIs[x]; 132 } 133 } 134 135 // set active list item 136 //this.activeLI = this.revertLIs[this.revertLIs.length-1]; 137 this.headerOuterHeight = $("#header .container:first").outerHeight(true); 138 setTimeout( function() { 139 cssMenus.stickyHeaderSpacer = $(".stickyHeader").outerHeight(true); 140 }); 141 142 // create click event for all list items 143 for (var x = 0; x < this.LIs.length; x++) { 144 if (multipleClasses("check", this.LIs[x].parentNode, "firstLevelWrapper")) { 145 var that = this; 146 147 if ($(this.LIs[x]).hasClass("displaySecondLevel")) { 148 var dropmenuID = $(this.LIs[x]).attr("id") + "Menu"; 149 cssMenus.dropit(this.LIs[x], dropmenuID); 150 } 151 152 $(this.LIs[x]).find("a").on('click', function(e) { 153 var addedClassModalOpen = false;
154 var isHeaderFoldout = false; 155 156 // Close the logintab when switching between first level nav items 157 if ($("#header .headerFoldout").css("display") == "block") { 158 // since the header becomes overlay 159 // restore the content to the correct position 160 $("#navigation").animate({ 161 top: "0px" 162 }, "fast"); 163 164 loginDropdown($("div.loginTab")); 165 isHeaderFoldout = true; 166 } 167 168 // Close the languageTab when switching between first level nav items 169 if ($('.languageDropdown').is(":visible")) { 170 $('.languageDropdown').slideUp('fast'); 171 } 172 173 if ($("html, body").hasClass("modal-open") && !isHeaderFoldout) { 174 addedClassModalOpen = true; 175 } 176 177 if (stickyHeaderBar) { 178 if (addedClassModalOpen) { 179 $("html, body").removeClass("modal-open"); 180 } else { 181 $("html, body").addClass("modal-open"); 182 } 183 } 184 185 if ($(this).hasClass("jewelButton")) { 186 var _this = this.parentNode.parentNode; 187 } else { 188 var _this = this.parentNode; 189 } 190 191 e.preventDefault(); 192 e.stopPropagation(); 193 194 var target = e.target, 195 tagName = $(target).prop('tagName'), 196 displayMenu = ( $(_this).hasClass("expanded") && tagName == "A" ), 197 fixedSection = $(_this).attr("id"), 198 elScroll = $("#"+fixedSection+"Menu"); 199 200 // check if releaseCode.stickyHeaderBar is activated 201 if (stickyHeaderBar) { 202 // Make the nav dropdown section scrollable, if dropdown section is visible 203 if (elScroll.css('display') == "none") { 204 var stickyHeaderSpacer = $(".stickyHeader").outerHeight(true); 205 resizeNavMenu(elScroll, cssMenus.stickyHeaderSpacer); 206 } 207 } 208 209 //Prepare for double click, continue to clickHandler doesn't come soon enough 210 clearTimeout(_this.clickTimeout); 211 212 var pendingClick = function () { 213 var dropmenuID = _this.firstChild.getAttribute("rel"); 214 that.secondLevel = document.getElementById(dropmenuID); 215 216 // if menuItem has no children, make primary menuItem clickable 217 if (that.secondLevel != null) { 218 cssMenus.dropit(_this, dropmenuID, displayMenu); 219 } else { 220 cssMenus.redirect(_this); 221 } 222 }; 223 _this.clickTimeout = setTimeout(pendingClick, that.delay); 224 }); 225 226 $(this.LIs[x]).find("a").on('dblclick', function (e) { 227 var _this = this.parentNode; 228 clearTimeout(_this.clickTimeout); 229 cssMenus.redirect(_this); 230 }); 231 } 232 } 233 } 234 }, 235 236 redirect: function (obj) { 237 // close dropdown before redirecting 238 cssMenus.hide(obj, true); 239 var redirectURL = $(obj).find("a").attr("href"); 240 window.location.href = redirectURL; 241 } 242} 243 244$(document).ready(function(){ 245 // executed at page load 246 cssMenus.init("navigation"); 247 248 // able to close the active dropdown by clicking outside the navigation area 249 // close the active dropdown before loading a page 250 $('body').on("click", function(e) { 251 var hideSecondLevel = false, 252 target = $(e.target); 253 254 if (target.closest("div#navigation").length === 0) { 255 hideSecondLevel = true; 256 } else { 257 if (target.is("a")) { 258 hideSecondLevel = true; 259 } 260 } 261 262 if (hideSecondLevel) { 263 var scrollTop = $(window).scrollTop(); 264 $("ul.firstLevelWrapper").children().each(function() { 265 if ($(this).hasClass("expanded")) { 266 cssMenus.hide($(this)[0], true); 267 $("html, body").removeClass("modal-open"); 268 } 269 }); 270 } 271 }); 272}); 273 274$(document).ready(function() { 275 // when the first level page loads, this code applies to the menu element that is open and which needs to scroll 276 // these styles are otherwise applied when the user clicks on a navigation item. Without them, the page jumps when you try to scroll 277 setTimeout(function() { 278 if (stickyHeaderBar) { 279 var menuElement = $("#navigation").find(".secondLevelWrapper.expanded"); 280 if (menuElement.length) { 281 var stickyHeaderSpacer = $(".stickyHeader").outerHeight(true); 282 resizeNavMenu(menuElement, stickyHeaderSpacer); 283 } 284 } 285 }); 286}); 287 288function resizeNavMenu (menuElement, stickyHeaderSpacer) { 289 var screenHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight, 290 elScroll = menuElement, 291 scrollHeight = 0; 292 293 // find the distance from the top of the stickyHeader to the top of the browsers viewport 294 var stickyHeader = $(".stickyHeader").get(0); 295 if (stickyHeader) { 296 var stickyHeaderRect = stickyHeader.getBoundingClientRect(); 297 stickyHeaderSpacer += stickyHeaderRect.top; 298 } 299 300 // there is no real height available 301 // temporarily show it invisibly 302 elScroll.css({display:'block', visibility:'hidden', position:'absolute'}); 303 scrollHeight = elScroll.get(0).scrollHeight; 304 // restore if needed 305 elScroll.css({display:'none', visibility:'', position:''}); 306 307 if (mobileBrowser) { 308 scrollHeight = (screenHeight - stickyHeaderSpacer); 309 } else { 310 if ((stickyHeaderSpacer + scrollHeight) > screenHeight) { 311 scrollHeight = (screenHeight - stickyHeaderSpacer); 312 } 313 } 314 315 elScroll.css({"height":scrollHeight + "px", "overflow":"auto"}); 316 // disable scrolling in the background, this prevents the stuttering 317 $("html, body").addClass("modal-open"); 318} 319 320// banners that appear above the sticky container, need to calculate the height of these elements 321// if element must be included in the sticky container (sticky_header.html) 322function getExtraStickyHeaderHeight () { 323 var stickyHeaderSpacer = 0; 324 var stickyElements = document.querySelectorAll('#adSlot_header, #thirdPartyHeader, .smartbanner, #siteSwitcher');
325 stickyElements.forEach(function(stickyElement) { 326 stickyHeaderSpacer += stickyElement.offsetHeight; 327 }); 328 return stickyHeaderSpacer; 329}
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.