1var menus = angular.module('menus', []); 2 3menus.service('siteNavigation', function () { 4 var linkIds = null; 5 var selected = null; 6 var selectedWatcher = null; 7 8 this.setLinkIds = function (val) { 9 linkIds = val; 10 if (angular.isArray(linkIds) && linkIds.length) { 11 this.setSelected(linkIds[linkIds.length - 1]); 12 } 13 }; 14 15 this.getLinkIds = function () { 16 return linkIds; 17 }; 18 19 this.setSelected = function (val) { 20 selected = val; 21 (selectedWatcher || angular.noop)(val); 22 }; 23 24 this.getSelected = function () { 25 return selected; 26 }; 27 28 this.watchSelected = function (fn) { 29 selectedWatcher = fn; 30 }; 31}); 32 33menus.controller('mainMenuCTRL', [ 34 '$timeout', 35 function ($timeout) { 36 var vm = this; 37 38 var linkIds = []; 39 40 vm.getLinkClass = function (id) { 41 return linkIds.indexOf(id) >= 0 ? 'selected' : ''; 42 }; 43 44 vm.init = function (handle, trail, refHandles, linkCount) { 45 linkIds = trail.map(function (t) { 46 return t.id; 47 }); 48 49 //initialise the array to keep track of what submenu's are open 50 vm.showSubmenu = new Array(linkCount); 51 }; 52 53 vm.toggleBurger = function (show) { 54 vm.burgerOpen = show || !vm.burgerOpen; 55 if (vm.burgerOpen) { 56 console.log(angular.element('nav#wpd-main-navigation-wrapper')); 57 $timeout(function () { 58 angular 59 .element('nav#wpd-main-navigation-wrapper') 60 .eq(0) 61 .focus(); 62 }); 63 } 64 if (!show) { 65 vm.closeSearch(); 66 } 67 }; 68 69 vm.toggleSearch = function (show) { 70 vm.searchOpen = show || !vm.searchOpen; 71 if (vm.searchOpen) { 72 $timeout(function () { 73 angular 74 .element('input#search') 75 .eq(0) 76 .focus(); 77 }); 78 } 79 if (!show) { 80 vm.closeBurger(); 81 } 82 }; 83 84 vm.closeBurger = function () { 85 vm.burgerOpen = false; 86 }; 87 88 vm.closeSearch = function () { 89 vm.searchOpen = false; 90 }; 91 92 vm.burgerOpen = false; 93 vm.searchOpen = false; 94 95 //On mouseover/mouseleave close any toggled submenus 96 //The toggle is primarily for keyboard users 97 //mask this functionality for mouse users 98 //This does not interfere with the css based hover functionality of the submenus 99 vm.closeAllToggledMenus = function() 100 { 101 untoggleSubmenus(-1); 102 }; 103 104 //Boolean array to control toggled visibility of the megamenu submenus 105 //Additional control for use with the chevrons (down triangles) - default hover behaviour untouched 106 vm.showSubmenu = []; 107 108 //Method for toggling the submenu on the main megamenu 109 vm.toggleSubmenu = function(linkIndex) 110 { 111 //Toggle the boolean 112 vm.showSubmenu[linkIndex] = !vm.showSubmenu[linkIndex]; 113 114 //Belt and braces 115 //Set all other values to false 116 //Incase we're jumping to other menu items without nicely untoggling the existing one 117 untoggleSubmenus(linkIndex); 118 }; 119 120 //Boolean array to control toggled visibility of the megamenu submenus 121 //Additional control for use with the chevrons (down triangles) - default hover behaviour untouched 122 vm.hoverSubmenu = function(linkIndex) 123 { 124 //This is a hover event - which we do not want to happen on mobile devices 125 //Problem occurs because IOS translates mouseover events into clicks 126 //So the user clicks and gets a mouseover event - which is undesireable 127 if (!iOS()) 128 { 129 //Toggle the boolean 130 vm.showSubmenu[linkIndex] = true; 131 132 //Belt and braces 133 //Set all other values to false 134 //Incase we're jumping to other menu items without nicely untoggling the existing one 135 untoggleSubmenus(linkIndex); 136 } 137 }; 138 139 //Is this an IOS device? 140 function iOS() { 141 return [ 142 'iPad Simulator', 143 'iPhone Simulator', 144 'iPod Simulator', 145 'iPad', 146 'iPhone', 147 'iPod' 148 ].includes(navigator.platform) 149 // iPad on iOS 13 detection 150 || (navigator.userAgent.includes("Mac") && "ontouchend" in document) 151 } 152 153 154 //Untoggle all submenu items except "skipindex". 155 var untoggleSubmenus = function(skipIndex) 156 { 157 var i; 158 for (i = 0; i < vm.showSubmenu.length; i++) { 159 if (i !== skipIndex) 160 { 161 vm.showSubmenu[i] = false;
162 } 163 } 164 }; 165 } 166]); 167 168/** 169 * Sidebar controller that is displayed on each child page 170 * responsible for setting active item and controlling menu 171 * visibility 172 * @author keiranc, lewisl 173 */ 174menus.controller('sidebarCTRL', [ 175 'siteNavigation', 176 function (siteNavigation) { 177 var vm = this; 178 179 vm.open = false; 180 181 /** 182 * Toggles menu open or closed 183 */ 184 vm.toggleOpen = function () { 185 vm.open = !vm.open; 186 }; 187 188 /** 189 * Initialiser function called in the view 190 * @param {String} handle the handle of the navigation menu 191 * @param {Array} trail list of navigation objects in the trail 192 */ 193 vm.init = function (handle, trail) { 194 siteNavigation.setLinkIds( 195 trail.map(function (t) { 196 return t.id; 197 }) 198 ); 199 }; 200 201 /** 202 * Used in view to determine selected link 203 * @param {*} id the id of the link 204 */ 205 vm.getLinkClass = function (id) { 206 var linkIds = siteNavigation.getLinkIds(); 207 if (!linkIds.length) return; 208 if (linkIds[linkIds.length - 1] === id) { 209 return 'current'; 210 } 211 return ''; 212 }; 213 } 214]); 215 216/** 217 * Used to control the 'section hints' at the bottom of content section pages 218 * @author lewisl 219 */ 220menus.controller('sectionHintCTRL', [ 221 '$timeout', 222 'siteNavigation', 223 function ($timeout, siteNavigation) { 224 var vm = this; 225 226 var prevLink, nextLink; 227 var $ = angular.element; 228 var sidebarLinks = $('.sidebar-menu li'); 229 var heading = $('.content-sidebar h2'); 230 231 vm.initLinks = function (data, headingData) { 232 // If we get supplied some data relating to the nav structure 233 // (i.e. being used as a page.navigation item) then we can 234 // reconstruct the DOM structure this page hints functionality 235 // relies on to save us rewriting it (for now...) 236 if (data && data.length) { 237 var sidebarEl = $('<ul class="sidebar-menu" />'); 238 sidebarEl.css({"display": "none"}); 239 $('body').append(sidebarEl); 240 data.forEach(function (link) { 241 var currentLink = $('<li />'); 242 currentLink.attr('id', 'sidebar-link-' + link.targetId); 243 currentLink.append('<a href="' + link.fullURL + '">' + link.linkTitle + '</a>'); 244 sidebarEl.append(currentLink); 245 246 if (link.isSelected) { 247 siteNavigation.setSelected(link.targetId); 248 } 249 }); 250 sidebarLinks = sidebarEl.find('li'); 251 } 252 if (headingData) { 253 var headingEl = $("<h2 />"); 254 headingEl.css({"display": "none"}); 255 headingEl.attr('id', 'section-heading-' + headingData.targetId); 256 if (headingData.isSelected) { 257 headingEl.addClass('selected'); 258 } 259 headingEl.append('<a href="' + headingData.fullURL + '">' + headingData.linkTitle + '</a>'); 260 $('body').append(headingEl); 261 heading = headingEl; 262 } 263 }; 264 265 var getPrevTerm = function (selected) { 266 var prev = $('#sidebar-link-' + selected).prev(); 267 if (prev.length === 0) { 268 return 'Overview'; 269 } 270 if (prev.index() === 0) { 271 return 'First'; 272 } 273 return 'Previous'; 274 }; 275 276 var getNextTerm = function (selected) { 277 if (heading.filter('.selected').length) { 278 return 'First'; 279 } 280 var next = $('#sidebar-link-' + selected).next(); 281 if (next.index() === sidebarLinks.length - 1) { 282 return 'Final'; 283 } 284 return 'Next'; 285 }; 286 287 var getPrevLink = function (selected) { 288 if (prevLink) { 289 return prevLink; 290 } 291 292 var prev = $('#sidebar-link-' + selected).prev(); 293 294 if (!prev.length) { 295 prev = $('.sidebar-menu li.current').prev(); 296 } 297 298 if (prev && prev.length) { 299 prevLink = { 300 text: prev.text(), 301 href: prev.find('a').attr('href') 302 }; 303 return prevLink; 304 } 305 306 if (heading.length && !heading.hasClass('selected')) { 307 var prevElement = heading.eq(0); 308 prevLink = { 309 text: prevElement.text(), 310 href: prevElement.find('a').attr('href') 311 }; 312 return prevLink; 313 } 314 return false;
315 }; 316 317 var getNextLink = function (selected) { 318 if (nextLink) { 319 return nextLink; 320 } 321 322 if (heading.filter('.selected').length) { 323 var next = sidebarLinks.eq(0); 324 nextLink = { 325 text: next.text(), 326 href: next.find('a').attr('href') 327 }; 328 return nextLink; 329 } 330 331 var nextElement = $('#sidebar-link-' + selected).next(); 332 if (nextElement && nextElement.length) { 333 nextLink = { 334 text: nextElement.text(), 335 href: nextElement.find('a').attr('href') 336 }; 337 return nextLink; 338 } 339 return false; 340 }; 341 342 siteNavigation.watchSelected(function (selected) { 343 vm.sectionHeading = 344 $('[id^=section-heading-]') 345 .first() 346 .text() 347 .trim() || 'this section'; 348 349 $timeout(function () { 350 vm.prevTerm = getPrevTerm(selected); 351 vm.nextTerm = getNextTerm(selected); 352 vm.prevLink = getPrevLink(selected); 353 vm.nextLink = getNextLink(selected); 354 }, 0); 355 356 }); 357 } 358]); 359 360menus.controller('socialIconsCtrl', [ 361 '$scope', '$templateCache', function ($scope, $templateCache) { 362 $scope.openDialog = function ($event) { 363 $event.preventDefault(); 364 365 // Gets the template from the templateCache. 366 var template = $templateCache.get('whatsapp-dialog-template.html'); 367 368 // Checks if the template is legit and no broken, or empty, or null, or undefined, 369 // I think you got the point :D Leave now, have a great day. 370 if (!template) { 371 console.error('Something got wrong with the template "whatsapp-dialog-template.html". Keep calm and... exterminate, exterminate...'); 372 373 return; 374 } 375 376 // Opens the dialog, it's that simple. 377 vex.dialog.open({ 378 input: template, 379 contentClassName: 'whatsapp-dialog', 380 buttons: [], 381 showCloseButton: true 382 }); 383 }; 384 } 385]);
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.