PageSourceSearch

https://customer.nationalgrid.co.uk/public/javascripts/angular.menus.js

js nationalgrid.co.uk collected 2026-09-24 09:02:25 UTC 12,362 bytes, 385 lines download raw bytes

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.