PageSourceSearch

https://baptist.org.uk/Images/Content/2019/Templates/62706/js/script.js?V=21feb2025

js baptist.org.uk collected 2026-09-24 09:13:41 UTC 36,631 bytes, 845 lines download raw bytes

1/*
2	Main ChurchInsight shop template Javascript/JQuery file.
3	WARNING - do not edit this file unless you know exactly what you are doing.
4	If you need advice, contact Endis/ChurchInsight Support.
5*/
6
7// This file runs after the web-page has loaded, as there is a "defer" attribute on the <script> tag in the HTML header.
8// The preloaded JQuery version is V1.10.2.
9
10$(document).ready(function () 
11{ 'use strict';
12
13// ############# Configuration settings ###############
14var sPath = '/Images/Content/2414/Templates/47288/images/'; // The template path. Must be updated if template is copied.
15// Custom values set here. Change for a particular customer.
16var CurrencySymbol = '£'; // could be $
17
18// Corrections for various hardware/browsers
19var P = navigator.platform;
20var bSmallAppleDevice = (P === 'iPhone' || P === 'iPad' || P === 'iPod');
21//var bBigAppleDevice = (P === 'MacIntel' || bSmallAppleDevice);
22
23var UA = navigator.userAgent;
24// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent for details.
25var bOnSafari = (UA.indexOf('Safari/') !== -1 && UA.indexOf('Chrome/') === -1 && UA.indexOf('Chromium/') === -1);
26
27// Edge works well with a mouse, but the touch needs adjusting.
28// It's a shame we cannot distinguish between touch and non-touch on Edge.
29var bOnEdge = (UA.indexOf('Edge/') !== -1);
30
31// IE is deprecated, but lots of people still use it. So we have to make some effort to support it for now.
32// IE works well with a mouse.
33var bOnIE = (UA.indexOf('Trident/') !== -1); // Trident is the rendering engine of IE.
34
35//alert(P + ' # ' + UA); // DEBUGGING line.
36
37// #################### Define some useful functions #######################
38
39// We have to put all functions here, as OSX does not allow functions to be inside if statements.
40
41// function to turn a slice name into a selector reference for the corresponding <section> tag
42function GetSectionTagRef(SliceName) {
43	return 'section.' + SliceName + ' ';
44}
45
46var SectionTag, SectionTags; // will be used to hold required slices
47function SectionTagExists(SliceName) {
48	if (SectionTags.hasClass(SliceName)) {
49		SectionTag = SectionTags.filter(GetSectionTagRef(SliceName));
50		if (SectionTag.length !== 0) { // at least one slice exists, great. You could have more than one in theory.
51			return true;
52		}
53	}
54	SectionTag = undefined; // remove all data.
55	return false;
56}
57
58function GetRefItem(SectionTag, Ref) {
59	if (typeof Ref === "string") {
60		if (Ref === '') { // allows us to return the section tag itself.
61			return SectionTag;
62		} else {
63			return SectionTag.find(Ref);
64		}
65	} else {
66		return Ref;
67	}
68}
69
70// A function to easily set JQuery toggles.
71// SectionTag is a $ variable.
72function ApplyToggleVisibilityOnClick(SectionTag, ClickRef, ToggleRef, iDelay, bShowToggleItemInitially) {
73
74	var ClickItem = GetRefItem(SectionTag, ClickRef);
75	var ToggleItem = GetRefItem(SectionTag, ToggleRef);
76
77	if (bShowToggleItemInitially) {
78		ToggleItem.show(0);
79	} else {
80		ToggleItem.hide(0);
81	}
82	// Note we add a function here. Since we are only using calling function arguements inside the function argument,
83	// variable scoping correctly works.
84	 ClickItem.click(function () {
85		ToggleItem.toggle(iDelay);
86	});
87}
88
89function ApplyHideOnClick(SectionTag, ClickRef, ToHideRef) {
90
91	var ClickItem = GetRefItem(SectionTag, ClickRef);
92	var ToHideItem = GetRefItem(SectionTag, ToHideRef);
93
94	 ClickItem.click(function () {
95		ToHideItem.hide(0);
96	});
97}
98
99function ApplyToggleClassOnClick(SectionTag, ClickRef, ToggleRef, ClassName) {
100
101	var ClickItem = GetRefItem(SectionTag, ClickRef);
102	var ToggleItem = GetRefItem(SectionTag, ToggleRef);
103
104	// Note we add a function here. Since we are only using calling function arguements inside the function argument,
105	// variable scoping correctly works.
106	 ClickItem.click(function () {
107		ToggleItem.toggleClass(ClassName);
108	});
109}
110
111// function to test if text exists.
112var sAttrText, sAttrText2, sAttrText3, sAttrText4; // Results come back in these variables.
113var DollarTextarea = $("<textarea/>"); // store this once.
114function TextExists(attrText, bSplit) {
115
116	if (attrText === undefined) {return false;}
117	if (attrText === null) {return false;}
118
119	var TextToProcess = attrText.trim();
120	if (TextToProcess === '') {return false;}
121
122	// decode the text, so that &amp;lt; becomes < etc.
123	// This works by turning into HTML and then turning back into text.
124	if (TextToProcess.indexOf('&') !== -1) { // we could use the .includes('&') method, but it is quite new, so some browsers can't cope.
125		TextToProcess = DollarTextarea.html(TextToProcess).text();
126	}
127	if (TextToProcess === '') {return false;}
128
129	sAttrText = ''; // set return values to blank.
130	sAttrText2 = '';
131	sAttrText3 = '';
132	sAttrText4 = '';
133	if (bSplit) {
134		var arrSplitText = TextToProcess.split('*');
135		sAttrText = arrSplitText[0].trim();
136		if (arrSplitText.length > 1) {sAttrText2 = arrSplitText[1].trim();}
137		if (arrSplitText.length > 2) {sAttrText3 = arrSplitText[2].trim();}
138		if (arrSplitText.length > 3) {sAttrText4 = arrSplitText[3].trim();}
139	} else {
140		sAttrText = TextToProcess;
141	}
142
143	return (sAttrText + sAttrText2 + sAttrText3 + sAttrText4 !== '');
144}
145 
146// define a function, so we can activate a SlickNav menu in a controlled way.
147var IEDy = 0, bEDopen = false;
148function ActivateMenu(SliceName) {
149	if (SectionTagExists(SliceName)) { // check if slice exists, and load into SectionTag if it does
150
151	  var SectionTagRef = GetSectionTagRef(SliceName);
152	  var RootMenuDeskTop = SectionTag.children('div.nav-menu').children('ul.root_menu');
153
154	  RootMenuDeskTop.slicknav({ // activate SlickNav for this slice.
155		prependTo: SectionTagRef + '> div.SlickNav_Wrapper',
156		allowParentLinks: true, // Top level items can be links
157		label: '',
158        duration:100,
159        easingOpen:'linear',
160        easingClose:'linear',
161		// Use hex escape characters here.
162		closedSymbol: '&#xe900', // a logical OR "V" symbol
163		openedSymbol: '&#xe901', // a nice up pointing ">" symbol
164		duplicate: true//bDesktopScreenPossible // only need to duplicate if the desktop menus are needed.
165	  });
166
167		var SlickNavLastItem = SectionTag.find('ul.slicknav_nav > li:last-child');
168		//Add extra links onto the SlickNav menu manually, to replace top-link log-out buttons etc.
169		var ExtraLink_1 = '<li class="ExtraLink Giving">
169<a class="top-link button Login" href="/Groups/374913/GivingHomeMission.aspx">GIVING<img alt="Icon" src="/Images/Content/2019/Templates/54496/images/LogoCircleArrow.png"></a></li>';
170		var ExtraLink_2 = '<li class="ExtraLink ContactUs"><a class="top-link button Login ContactUs" href="/Groups/220185/Contact_Us.aspx">CONTACT US</a></li>';
171		var ExtraLink_3 = '<li class="ExtraLink SearchOpen"></li>';
172		$(ExtraLink_2 + ExtraLink_1 + ExtraLink_3).insertAfter(SlickNavLastItem);
173
174		if (0 && bOnTouchDevice && bDesktopScreenPossible) { // have to do more work on menus.
175
176			// Having made the SlickNav menu - delete what we don't want.
177
178			SectionTag.children("div.SlickNav_Wrapper").children("div.slicknav_menu").children('ul.slicknav_nav').find('li.SlickNavNotNeeded').remove();
179
180			// deactivate the top level <a> tag in the desk-top version so touch-screens work correctly.
181			// The link goes nowhere, but retains all the styling.
182			RootMenuDeskTop.children("li.has_sub_menu").children('a').removeAttr("href");
183		}
184
185		// Add a close menu icon into slickNav.
186		var SlickNavIcon = SectionTag.find('span.slicknav_icon');
187		$('<div class="SlickNavCloseIcon"></div>').insertAfter(SlickNavIcon);
188
189		// apply all the visibility on-clicks to make the menu slice work.
190
191		// Find some commonly used items.
192		//var SearchOverlay = SectionTag.find("div.search-overlay");
193		var SlickNavBtn = SectionTag.find("a.slicknav_btn");
194      	var Mask = BodyTag.find('div.MobileMenuMask');
195
196		//ApplyToggleVisibilityOnClick(SectionTag, "li.ExtraLink.SearchOpen", SearchOverlay, 0, false);
197		//ApplyToggleVisibilityOnClick(SectionTag, "div.top-link-wrapper a:last-child", SearchOverlay, 0, false);
198		//ApplyHideOnClick(SectionTag, "img.search-close", SearchOverlay);
199		//ApplyHideOnClick(undefined, SlickNavBtn, SearchOverlay);
200		// Toggles for menu-bars and menu-close icons
201		ApplyToggleVisibilityOnClick(undefined, SlickNavBtn, SlickNavIcon, 0, true); // no delay on the toggle.
202		ApplyToggleVisibilityOnClick(SectionTag, SlickNavBtn, "div.SlickNavCloseIcon", 0, false); // no delay on the toggle.
203      	ApplyToggleVisibilityOnClick(undefined, SlickNavBtn, Mask, 0, false); // no delay on the toggle.
204      	ApplyToggleClassOnClick(SectionTag, SlickNavBtn, '', 'SlickNavFullWidth'); 
205      	SlickNavBtn.click(function(){
206          if(!bEDopen){
207            IEDy = window.pageYOffset;
208          	window.scrollTo(0,0);
209          } else {
210            window.scrollTo(0,IEDy);
211          }
212          bEDopen = !bEDopen;
213        });
214      	// Link white-eye-glass to hidden search button.
215        //var HiddenSearchBox = SearchOverlay.find('input.button');
216  		//SearchOverlay.find('img.search-EyeGlass').click(function(){HiddenSearchBox.click();}); // set up the click.
217
218		// Need autocomplete="off" to be added to the search box <input> tag.
219		// This stops horrible browser autocomplete text from appearing.
220		//SearchOverlay.find('input.text').attr("autocomplete","off");
221
222	  }
223}
224
225
226// Remove the Discount column, if it is all zeros.
227function RemoveDiscountColumnIfAllZeros(sTableFind, sTdFind) {
228	var Table = SectionTag.find(sTableFind);
229	if (Table.length === 1) {
230		var TdsToSearch = Table.find(sTdFind);
231		var bFoundDiscountColumn = false, bHideDiscountColumn = true;
232		TdsToSearch.each(function() {
233			var tdText = $(this).text().trim();
234			if (tdText === 'Discount') {
235				bFoundDiscountColumn = true;
236			} else if (tdText !== CurrencySymbol + '0.00') {
237				bHideDiscountColumn = false;
238			}
239		});
240		if (bFoundDiscountColumn && bHideDiscountColumn) {
241			TdsToSearch.hide();
242		}
243
244		var bBasketTable = (sTableFind === 'table.gridstyle');
245
246		// Remove the .00 off of prices, and any commas, to save space.
247		if (window.innerWidth < iSmWidth) {
248			Table.find('tr:not(:first-child) td:not(:first-child)').each(function() { // have to search sub-tables too with this query string.
249				var Td = $(this);
250				var tdText = Td.text().trim();
251				if (tdText.length >= 5) { // '£0.00' is 5 chars, so look for at least this length, to avoid 0 length strings etc.
252					if (tdText.substr(0, 1) === CurrencySymbol || tdText.substr(0, 8) === '&nbsp; ' + CurrencySymbol) {
253						var bUpdateText = false;
254						if (tdText.indexOf(',') !== -1) {
255							tdText = tdText.replace(',', '');
256							bUpdateText = true;
257						}
258						if (tdText.indexOf('.00') !== -1) {
259							tdText = tdText.replace('.00', '');
260							bUpdateText = true;
261						}
262						// if (tdText.substr(-3) === '.00') {
263							// tdText = tdText.substr(0, tdText.length - 3);
264							// bUpdateText = true;
265						// }
266						if (bUpdateText) {
267							Td.text(tdText);
268						}
269					}
270				}
271			});
272		}
273
274		if (!bBasketTable) {
275			Table.find('> tbody > tr:not(:first-child):not(:last-child):not(:nth-last-child(2)) td:first-child').each(function() {
276				var Td = $(this);
277				var tdText = Td.text().trim();
278				if (tdText.indexOf('(by ') !== -1) {
279					Td.text(tdText.replace('(by ',' (by ')); // add the missing space before the bracket here.
280				}
281			});
282		} else {
283			Table.find('input[type="text"]').attr('autocomplete','off'); // none of this on qty and price boxes.
284		}
285	}
286}
287
288// We use this to re-structure the Delivery and Credit Card tables.
289function MakeTableIntoOneColumn(sTableFind, bAdjustSelectOptionText) {
290	var Table = SectionTag.find(sTableFind);
291	var TableTr = Table.find('> tbody > tr');
292	if (TableTr.length === 1) { // should be only 1 tr.
293
294		var Td2 = TableTr.children('td:last-child');
295		$('<tr></tr>').insertAfter(TableTr);
296		var Tr2 = TableTr.next();
297		Td2.appendTo(Tr2);
298
299		// While we are here, remove the .00 of prices in the delivery ddl, and the brackets around the price.
300		if (bAdjustSelectOptionText && window.innerWidth < iSmWidth) {
301			Table.find('select[id*="_ddlDelivery_"] option').each(function() {
302				var Option = $(this);
303				var optionText = Option.text().trim();
304				if (optionText.length >= 7) { // '(£0.00)' is 7 chars, so look for at least this length, to avoid 0 length strings etc.
305					if (optionText.substr(-4) === '.00)') {
306						optionText = optionText.substr(0, optionText.length - 4) + ')'; // put the bracket back on for now.
307					}
308					optionText = optionText.replace(' (' + CurrencySymbol, ' ' + CurrencySymbol);
309					Option.text(optionText.substr(0, optionText.length - 1));
310				}
311			});
312		}
313
314 		Table.show().css('visibility','visible'); // now show the table, as it was hidden in CSS.
315	}
316}
317                               
318function FixHotPicksModule() {
319	if (SectionTagExists('slice_ShopHotPicks')) { // check if slice exists, and load into SectionTag if it does
320		var Imgs = SectionTag.find('img[width]');
321		if (Imgs.length !== 0) {
322			Imgs.each(function() {
323				var Img = $(this);
324				var src = Img.attr('src');
325				var T = src;
326				src = src.replace('/Publisher/GetResizedImage.aspx?size=THUMBNAIL&url=','');
327				if (src !== T) {
328					Img.attr('src',src);
329				}
330			});
331		} else { // No hotpicks with images, so hide everything.
332			SectionTag.hide();
333		}
334	}
335}
336 
337function ActivateBlockImages(SliceName) {
338	if (SectionTagExists(SliceName)) { // check if slice exists, and load into SectionTag if it does
339		SectionTag.find("div.image_blocks img" ).each(function() {
340			if (TextExists($(this).attr('alt'), true)) { // check if there is any alt text.
341              	if(sAttrText3 === ''){sAttrText3 = 'View category';}
342				var cardGridCaption = '<div class="image_block_title_wrapper"><div class="image_block_title">' + sAttrText + '</div><div class="image_block_text">' + sAttrText2 + '</div><div class="image_block_textB">' + sAttrText3 + '</div></div>';
343                if(sAttrText4 !== ''){
344                  cardGridCaption = cardGridCaption.replace('<div class="image_block_title"','<div  class="image_block_title" style="color:' + sAttrText4 + ';"');
345                  cardGridCaption = cardGridCaption.replace('<div class="image_block_text"','<div  class="image_block_text" style="color:' + sAttrText4 + ';"');
346                }
347                $(cardGridCaption).insertAfter( this );
348			}
349			$(this).removeAttr('title'); // remove the title attribute so that pop-up text does not appear.
350		});
351	}
352}
353 
354var LogoBannerSlides, LogoGalleryUL, LogoBxSlider, iLastNumLogos = -1;
355function AjdustBxSliderOnWindowResize(bFirstTimeCall) {
356	if (bSliderActive) {
357
358		var iMarginWidth = 40;
359		var iLogoMaxAllowedWidth = 180 + iMarginWidth;
360
361		var iBxWidth = LogoBannerSlides.outerWidth();
362		var iNumOfLogosVisible = Math.ceil((iBxWidth + iMarginWidth - 0.001) / iLogoMaxAllowedWidth); // account for rounding errors.
363
364		if (iNumOfLogosVisible !== iLastNumLogos) { // only do anything if we need to change the number of visible images.
365			iLastNumLogos = iNumOfLogosVisible;
366
367			var NewLogoWidth = (iBxWidth - (iNumOfLogosVisible - 1) * iMarginWidth) / iNumOfLogosVisible;
368
369			var BxValues = {
370				mode: 'horizontal',
371				auto: false,
372				pause: 5000,
373				speed: 500,
374				pager: false,
375				controls: true,
376				preloadImages: 'all',
377				touchEnabled: false,
378				minSlides: iNumOfLogosVisible, // Carousel options.
379				maxSlides: iNumOfLogosVisible,
380				moveSlides: 1,
381				slideWidth: NewLogoWidth, // (1090 - 6*20) / 7 (slide controls are outside 1170px width.)
382				slideMargin: iMarginWidth,
383				randomStart: true
384			};
385
386			if (bFirstTimeCall) {
387				LogoBxSlider = LogoGalleryUL.bxSlider(BxValues);
388			} else {
389				LogoBxSlider.reloadSlider(BxValues); // reload rather than start again.
390			}
391		}
392	}
393}
394
395var bSliderActive = false;
396function ActivateBxSlider(SliceName) {
397	if (SectionTagExists(SliceName)) { // check if slice exists, and load into SectionTag if it does
398
399      var HotPicks = SectionTag.next();
400      if(HotPicks.hasClass('HiddenHotpicks') && HotPicks.children().length > 0){
401        
402        var UL = SectionTag.find('ul.gallery_ul');
403        HotPicks.find('img[style]').each(function(){ // only get images with a [style] set.
404        	var ThisImg = $(this);
405            var SRC = ThisImg.attr('src').replace('/Publisher/GetResizedImage.aspx?size=THUMBNAIL&url=','');
406            var P = ThisImg.parent();
407          	var ItemLink = P.attr('href');
408          	var Bs = P.parent().next().find('b');
409          	var HTMLa = '<img src="' + SRC + '">';
410            var HTMLb = '<div class="HoptPickTitle">' + Bs.eq(0).text().trim() + '</div>';
411            var HTMLc = '<div class="HoptPickPrice">Price: <b>' + Bs.eq(1).text().trim() + '</b></div>';
412            var HTMLd = '<a href="' + ItemLink + '">More Details</a>';
413          	var S = '<li class="gallery_li">' + HTMLa + HTMLb + HTMLc + HTMLd + '</li>';
414            $(S).appendTo(UL);
415        });
416        
417        bSliderActive = true;
418        // ul.gallery_ul must be displayed before bx-slider can be applied.
419        // So since we hide it while the page was loading, we show it now.
420        var bannerSlides = SectionTag.find('div.bannerSlides'); // use a "find" here, as structure of slices varies.
421        bannerSlides.show(0);
422        LogoBannerSlides = bannerSlides; // get a handle.
423        var gallery_ul = bannerSlides.children('ul.gallery_ul');
424        LogoGalleryUL = gallery_ul;
425        AjdustBxSliderOnWindowResize(true);
426      }
427	}
428}
429
430// Deal with screen resizes. This is NOT a polling routine.
431function RunOnScreenResize(){
432	AjdustBxSliderOnWindowResize(false); // change the number of logos to show. Does not change heights.
433}
434
435// ########################## Check various conditions #############################
436
437var bOnTouchDevice = ('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0);
438
439var iDeskTopWidth = 992;
440var iMobileScreenAllowence = 64; // Because of other stuff on a screen, you have to assume the browser window could get bigger on a rotation.
441var iScreenWidthToCheck = screen.width + iMobileScreenAllowence;
442var iScreenHeightToCheck = screen.height + iMobileScreenAllowence;
443var bDesktopScreenPossible = (iScreenWidthToCheck >= iDeskTopWidth) || (iScreenHeightToCheck >= iDeskTopWidth);
444
445var iSmWidth = 768;
446
447var BodyTag = $('body');
448if(bOnIE){BodyTag.addClass('bOnIE');}
449var bOnSystemPopupPage = BodyTag.hasClass('system_popup'); // T&C's page is one of these.
450var bUserLoggedIn = BodyTag.hasClass('logged_in_user');
451var bOnShopPage = !bOnSystemPopupPage;
452
453SectionTags = BodyTag.find('section'); // Store all the section tags to speed up later code.
454var bOnLandingPage = SectionTags.hasClass('slice_SlideShowLogos');
455
456// #######################################
457// # Menu data changes
458// #######################################
459
460// We make the required adjustments to the one set of menu HTML on the page, before cloning it and activating all the copies.
461
462var ulModuleRootMenu = BodyTag.find('ul.root_menu');
463var bMenuPresent = (ulModuleRootMenu.length !== 0);
464if (bMenuPresent) {
465
466  // Set up the search icon in the search box.
467  if(bDesktopScreenPossible){
468    var DeskTopSearchBox = BodyTag.find('header div.top-link-wrapper div.search-form');
469    var HiddenSearchBox = DeskTopSearchBox.find('input.button');
470    DeskTopSearchBox.find('input.text').attr("autocomplete","off");
471    $('<img alt="Icon" src="/Images/Content/2019/Templates/54496/images/IconEyeGlassBlue.png">
471').appendTo(DeskTopSearchBox);
472    DeskTopSearchBox.find('img').click(function(){HiddenSearchBox.click();}); // set up the click.
473  }
474
475  // Only keep some of the top-level menu items.
476  ulModuleRootMenu.find('li.menu_item_level_1').each(function() {
477    var ThisLi = $(this);
478    var Ahref = ThisLi.children('a').attr('href');
479    if (
480      	!Ahref.startsWith('/Groups/213223/') &&
481        !Ahref.startsWith('/Groups/220180/') &&
482        !Ahref.startsWith('/Groups/220181/') &&
483        !Ahref.startsWith('/Groups/220184/') &&
484        !Ahref.startsWith('/Groups/220182/') && // Latest Updates
485      	!Ahref.startsWith('/Shop/') &&
486        !Ahref.startsWith('/Hubb?')
487    ) {
488    	ThisLi.hide();
489    }
490  });
491    
492   /* remove sub menus from Home */
493   // This assumes that the home menu is the first item with a sub menu.
494  var HomeMenuLi = ulModuleRootMenu.children('li:first-child');
495  HomeMenuLi.children('ul').remove();
496  HomeMenuLi.removeClass('has_sub_menu'); // remove class
497  //HomeMenuLi.children('a').attr("href","/"); // replace link with base domain reference, not a group reference.    
498    
499  // remove copies of 1st item elements in dropdown sub-menu.
500  ulModuleRootMenu.find('li.menu_item_level_2:first-child').each(function() {
501
502	var ThisLi = $(this);
503	if(ThisLi.children("a[href^='/MyArea/']").length === 0) { // only if not a link into /MyArea/...
504
505	  if(ThisLi.siblings().length === 0) { // no other <li> so it is the only entry
506		var ul = ThisLi.parent();
507	    ul.parent().removeClass('has_sub_menu'); // remove class from the <li> at the level above
508		ul.remove(); // delete whole parent <ul>
509
510	  } else {
511		if (bOnTouchDevice && bDesktopScreenPossible) {
512			// On a touch device, the copies of the level one links at the 2nd level have to be kept for the desktop menus.
513			// But in the SlickNav menus, these 2nd level links are not needed.
514			// So we mark the items so we can delete them later, after data is copied into the SlickNav menu.
515			ThisLi.addClass('SlickNavNotNeeded'); // Mark the 2nd level <li> tag.
516		} else {
517			// Not on a touch screen, so Desktop and SlickNav menus will be the structurally the same.
518			ThisLi.remove(); // so just remove this <li> tag
519		}
520	  }
521	}
522  });
523
524	// #######################################
525	// # SlickNav menus V1.0.10
526	// #######################################
527
528	ActivateMenu('slice_Header_L');
529
530  // Set up Search box inside SlickNav
531  var DeskTopSearchBoxM = BodyTag.find('header div.SlickNav_Wrapper div.search-overlay');
532  var LIs = BodyTag.find('header div.SlickNav_Wrapper ul.slicknav_nav li.ExtraLink.SearchOpen');
533  DeskTopSearchBoxM.appendTo(LIs);
534  var HiddenSearchBoxM = DeskTopSearchBoxM.find('input.button');
535  DeskTopSearchBoxM.find('input.text').attr("autocomplete","off");
536  $('<img alt="Icon" src="/Images/Content/2019/Templates/54496/images/IconEyeGlassBlue.png">').appendTo(DeskTopSearchBoxM);
537  DeskTopSearchBoxM.find('img').click(function(){HiddenSearchBoxM.click();}); // set up the click.
538
539} // end of if bNeedMenus
540
541// Here do things ONLY needed on a home page.
542var ShopSlickNavBtn; 
543if (bOnShopPage) {
544
545	var bInShopCheckout = false;
546	if (SectionTagExists('slice_ShopCheckOut')) { // check if slice exists, and load into SectionTag if it does.
547
548		if (SectionTag.find('div.container > div').length === 0) {
549			SectionTag.hide(); // if check-out is empty, then hide.
550            if (SectionTagExists('slice_ShopTermsAndConditions')) {
551      		  SectionTag.addClass('Grey');
552    		}
553
554		} else {
555			bInShopCheckout = true;
556
557			MakeTableIntoOneColumn('table.delivery-container', false);
558			MakeTableIntoOneColumn('table.delivery-container > tbody > tr:nth-child(2) > td > table:first-of-type', true); // has delivery select in it.
559			MakeTableIntoOneColumn('table#tblPaymentDetails', false);
560
561			// This is the shop checkout Basket.
562			RemoveDiscountColumnIfAllZeros('table.gridstyle[id$=_dgItems]', '> tbody > tr:not(:last-child) > td:nth-child(5)');
563			// This is the table on the checkout confirm page.
564			RemoveDiscountColumnIfAllZeros('div#dvFullItemDetails > table > tbody > tr > td > table', '> tbody > tr:not(:last-child):not(:nth-last-child(2)) > td:nth-child(4)');
565			
566			// Change the item delete icon.
567			SectionTag.find('img[src="/Admin/Images/icons/delete.png"]').attr('src', sPath + 'IconBin.png');
568			
569			// Enable Revelation registration page CSS to run if needed.
570			var ShopLogin = SectionTag.find('div[id$="_divNewCustomer"]');
571			if (ShopLogin.length === 1) {
572				var ReturningCustomers = SectionTag.find('div[id$="_pnlReturningCustomer"]');
573				if (ReturningCustomers.length === 0) { // will be 0 if shop-only accounts are disabled.
574					ShopLogin.addClass('_user_registration_aspx');
575					ShopLogin.children('table').addClass('shadedbox');
576				}
577			}
578          
579			var CartItemsInCheckoutTable = SectionTag.find('table[id$=_dgCartPageItems]');
580			if (CartItemsInCheckoutTable.length === 1) {
581				CartItemsInCheckoutTable.find('img').each(function() {
582					var Img = $(this);
583					var src = Img.attr('src');
584					var T = src;
585					src = src.replace('/Publisher/GetResizedImage.aspx?size=mini_thumbnail&url=','');
586					if (src !== T) {
587						Img.attr('src',src);
588					}
589				});
590			}
591
592			// Do these last, as we re-define SectionTag.
593			if (SectionTagExists('slice_ShopBasket')) {
594				SectionTag.hide(); // if check-out is visible, then hide shop basket, to avoid confusion.
595			}
596			if (SectionTagExists('slice_ShopFind')) {
597				SectionTag.hide(); // if check-out is visible, then hide shop find, to avoid confusion.
598			}
599			if (SectionTagExists('slice_ShopBreadCrumbs')) {
600				SectionTag.hide(); // if check-out is visible, then hide shop breadcrumbs, to avoid confusion.
601			}
602			if (SectionTagExists('slice_ShopHotPicks')) {
603				SectionTag.hide(); // if check-out is visible, then hide shop breadcrumbs, to avoid confusion.
604			}
605		}
606	}
607
608	if (SectionTagExists('slice_ShopCatNav')) { // check if slice exists, and load into SectionTag if it does
609
610      var SectionTagRef = GetSectionTagRef('slice_ShopCatNav');
611      var ShopCatNavRootA = SectionTag.find('ul#ShopCatNavRoot');
612      var ShopCatNavRootB;
613      var SIL = SectionTags.filter(GetSectionTagRef('slice_ShopItemList')).eq(0); // only the first such section (not eg. related items)
614      var bHasSomeItems = SIL.find('div[id]').length > 0;
615      var b = SIL.length > 0;
616      if(b){b = SIL.hasClass('CanHaveSideBar');}
617      if(b){b = bHasSomeItems;} 
618      
619      var bEmptySearch = false;
620      if(!bHasSomeItems){
621        bEmptySearch = SIL.find('div.ShopModuleItemsList').text().trim() === 'Sorry, no items were found.';
622      }
623  	  if(bEmptySearch){SIL.addClass('EmptySearch');}    
624  
625      var bNeedLeftHandMenu = bDesktopScreenPossible && b;
626      if(bNeedLeftHandMenu){ShopCatNavRootB = SectionTag.find('ul#ShopCatNavRoot').clone();}
627
628      ShopCatNavRootA.slicknav({ // activate SlickNav for this slice.
629        prependTo: SectionTagRef + ' div.SlickNavA',
630        allowParentLinks: true, // Top level items can be links
631        label: 'Shop Categories',
632        // Use hex escape characters here.
633        closedSymbol: '&#xe900', // a logical OR "V" symbol
634        openedSymbol: '&#xe901', // a nice up pointing ">" symbol
635        duplicate: false // never need the original.
636      });
637      SectionTag.find('ul#ShopCatNavRoot > li:first-child > a').text('Shop Home');
638
639      // Add a close menu icon into slickNav.
640      var SlickNavIcon = SectionTag.find('span.slicknav_icon');
641      $('<div class="SlickNavCloseIcon"></div>').insertAfter(SlickNavIcon);
642
643      // apply all the visibility on-clicks to make the menu slice work.
644
645      // Find some commonly used items.
646      ShopSlickNavBtn = SectionTag.find("a.slicknav_btn");
647      // Toggles for menu-bars and menu-close icons
648      ApplyToggleVisibilityOnClick(undefined, ShopSlickNavBtn, SlickNavIcon, 0, true); // no delay on the toggle.
649      ApplyToggleVisibilityOnClick(SectionTag, ShopSlickNavBtn, "div.SlickNavCloseIcon", 0, false); // no delay on the toggle.
650
651      // Build second version 
652      if(bNeedLeftHandMenu){
653      	  ShopCatNavRootB.slicknav({ // activate SlickNav for this slice.
654			prependTo: SectionTagRef + ' div.SlickNavB',
655			allowParentLinks: true, // Top level items can be links
656			label: 'Shop Categories',
657			// Use hex escape characters here.
658			closedSymbol: '&#xe900', // a logical OR "V" symbol
659			openedSymbol: '&#xe901', // a nice up pointing ">" symbol
660			duplicate: false // never need the original.
661		  }); 
662          
663      } else {
664      	SectionTag.find('div.SlickNav_Wrapper.SlickNavA').addClass('NoLeftBar');
665        SectionTag.find('div.SlickNav_Wrapper.SlickNavB').hide();
666      }
667    
668    }
669
670	if (!bInShopCheckout) {
671		if (SectionTagExists('slice_ShopBasket')) {
672			
673			// Fix basket display
674			var tdBasketTotal = SectionTag.find('table tr:last-child td'); 
675			var tdBasketTotalB = tdBasketTotal.children('b'); // remember the <b> tag!
676			var BasketText = tdBasketTotalB.text();
677			BasketText = BasketText.substr(BasketText.indexOf(CurrencySymbol));
678			tdBasketTotalB.text(BasketText);
679			
680			// Create the shop basket overlay
681			var BasketOverlay = SectionTag.clone().hide(); // might as well set this to be hidden.
682			BasketOverlay.insertAfter(SectionTag);
683			BasketOverlay.removeClass('slice_ShopBasket').addClass('slice_ShopBasketOverlay');
684			BasketOverlay.find('input').attr('value','Checkout / Edit basket');
685			$('<div id="BasketOverlayTop"><span>&#xe93a;</span><span id="CloseBasketOverlay">&#xea0f;</span></div>').prependTo(BasketOverlay.find('div.ShopBasket'));
686			ApplyHideOnClick(BasketOverlay, 'span#CloseBasketOverlay', '');
687			ApplyToggleVisibilityOnClick(undefined, SectionTag.find('table'), BasketOverlay, 0, false); // no delay on the toggle.
688			
689			// Now fix the basket display again, to remove any Net total info.
690			tdBasketTotal.children('br').remove();
691			tdBasketTotal.children('small').remove();
692		}
693
694		if (SectionTagExists('slice_ShopFind')) { // check if slice exists, and load into SectionTag if it does.
695
696			var InputFind = SectionTag.find('input[id$="_tbSearch"]');
697			InputFind.attr('placeholder','Search current shop category');
698
699			// Code to fix the advanced search.
700			// var InputTag = SectionTag.find('input[id$="_chkSearchSubsections"]');
701			// if (InputTag.length === 1) {
702				// var SelectLocation = SectionTag.find('select[id$="_ddlLocation"]')
703				// var InTrTag = SelectLocation.parent().parent();
704				// var SubCatTrTag = InTrTag.next(); // next sibling.
705				// var sAttrModeValue = InTrTag.attr('mode');
706				// var sAttrStyleValue = InTrTag.attr('style');
707				// SubCatTrTag.attr('mode', sAttrModeValue);
708				// SubCatTrTag.attr('style', sAttrStyleValue);
709			// }
710		}
711
712		if (SectionTagExists('slice_ShopBreadCrumbs')) { // check if slice exists, and load into SectionTag if it does.
713			if (SectionTag.find('span.ShopBreadCrumbs').length === 0) {
714				SectionTag.hide();
715			}
716		}
717      
718		FixHotPicksModule();
719
720		if (SectionTagExists('slice_ShopItemList')) { // check if slice exists, and load into SectionTag if it does.
721          
722			// Change the missing image picture.
723			SectionTag.find('img[src*="/Shop/Admin/Images/noimage_"]').attr('src', sPath + 'NoImageAvailable.png');
724
725			// Add a block wrapper around all the div[id]'s, so that the shop results page will render correctly.
726			var Divs = SectionTag.find('div.ShopModuleItemsList > div[id]');
727			if (Divs.length !== 0) {
728				var ItemWrapper = $('<div class="ItemsWrapper isolate_element"></div>'); // need to add isolate_element to this element.
729				ItemWrapper.insertBefore(Divs.first());
730				Divs.appendTo(ItemWrapper);
731			}
732          
733          	// Build the left-hand side shop-nav
734          // We use SectionTag.eq(0), as there may be multiple section.slice_ShopItemList on a page, eg 'Also bought' etc.
735          if(bDesktopScreenPossible && SectionTag.eq(0).hasClass('CanHaveSideBar')){
736          	var SlickNav = BodyTag.find('section.slice_ShopCatNav div.SlickNavB');
737          	var ItemList = SectionTag.eq(0).find('div.ItemsWrapper');
738          	ItemList.addClass('LeftSideBar');
739          	$('<section class="slice_ShopCatNav LeftSideBar"></section>').insertBefore(ItemList);
740            var LeftShopCatNav = SectionTag.eq(0).find('section.slice_ShopCatNav');
741            SlickNav.appendTo(LeftShopCatNav);
742          	SlickNav.find('ul#ShopCatNavRoot > li:first-child > a').text('Shop Home');
743          	SlickNav.find('a.slicknav_btn').click(); // open the menu.
744          	SectionTag.eq(0).find('div.LeftInformation').removeClass('HideElement').appendTo(LeftShopCatNav);
745			$('<div class="LinkBlocker"></div>').prependTo(LeftShopCatNav.find('div.slicknav_menu'));
746          }
747          
748			var spanSectionDescription = SectionTag.find('span[id$="_lblSectionDescriptionText"]');
749			if (spanSectionDescription.text() === '') {
750				spanSectionDescription.hide();
751			}
752
753			SectionTag.find('input[type="text"]').attr('autocomplete','off');
754
755          	// Change footer alphabetic links to just numbers.
756          	var LastDiv = SectionTag.find('div.ShopModuleItemsList > div:last-child span.BelowTabs div.BelowTabs div:last-child');
757            var Links = LastDiv.find('a[id*="_ctlAZNavigator_"]');
758            if(Links.length > 0){
759              SectionTag.next().next().children().hide(); // hide normal T&Cs section.
760              var i=1, CurrentLink=0;
761              Links.each(function(){
762                var ThisAtag = $(this);
763                var S = i + '&nbsp; &nbsp;';
764                if(i > 1){S = '&nbsp; &nbsp;' + S;}
765                if(ThisAtag.hasClass('aspNetDisabled')){
766                    ThisAtag.addClass('CurrentPage').html(S);
767                    CurrentLink = i;
768                } else {
769                    ThisAtag.html(S);
770                }
771                i++;
772              });
773              //console.log(CurrentLink + ' ' + Links.length);
774              if(CurrentLink < Links.length){
775                  var Aclone = Links.eq(CurrentLink).clone().addClass('NextPage').text('Next Page');
776                  Aclone.appendTo(LastDiv);
777                  $('<i>&nbsp;</i>').appendTo(LastDiv);
778              }
779              $('<a class="TaC" href="javascript:OpenShopTermsAndConds();">Shop T&amp;Cs</a>').appendTo(LastDiv);
780            }
781		}
782      
783      	if (SectionTagExists('slice_ShopItemDetails')) { // check if slice exists, and load into SectionTag if it does.
784
785			// Change the missing image picture.
786			SectionTag.find('img[src*="/Shop/Admin/Images/noimage_"]').attr('src', sPath + 'NoImageAvailable.png');
787
788			var ATag = SectionTag.find('a[title="Zoom in"]');
789			var Img = ATag.find('> img');
790			Img.insertAfter(ATag); // move the img tag, outside the <a> tag.
791			// ATag.hide(0); // This should already be hidden in CSS.
792			
793		} else if (SectionTagExists('slice_ShopMyOrders')) { // check if slice exists, and load into SectionTag if it does.
794			
795			var iNumTables = SectionTag.find('table').length;
796			if (iNumTables > 1) { // we are on an order details page, not the order list page.
797				var sTableSelector = '> div > div > table:first-of-type'; // this is the table that holds 2 sub-tables.
798				if (window.innerWidth < iSmWidth) {
799					MakeTableIntoOneColumn(sTableSelector, false);
800				} else {
801					SectionTag.find(sTableSelector).show();
802				}
803				RemoveDiscountColumnIfAllZeros('table[id$="_dgItems"]', '> tbody > tr > td:nth-child(5)');
804			}
805		}
806
807	}
808}
809
810if (bSmallAppleDevice) {
811	// Parallex images are often a mess on small apple devices, so add a tag onto the <body> tag so we can take evasive action.
812	BodyTag.addClass('OnSmallAppleDevice');
813}
814 
815 
816 if(bOnLandingPage){
817   // Category gallery
818   ActivateBlockImages('slice_image_blocks_3');
819   
820   // Hotpicks gallery.
821   ActivateBxSlider('slice_SlideShowLogos');
822   
823  if (bSliderActive) {
824      window.addEventListener("resize", function(){RunOnScreenResize();}, false);
825  }
826 }
827 
828// Sort out login/logout/register/web-office links
829if (bUserLoggedIn) {
830	var SB = BodyTag.find('div.HiddenStatusBar');
831	if (SB.length === 1) {
832		var bWebOfficeActive = (SB.find('a.weboffice_link').length === 1);
833		if (!bWebOfficeActive) { // Need to hide WO links.
834			BodyTag.find('section.NewsLetterFooter a.FooterWebOffice').hide();
835		}
836	}
837}
838
839// Fix the cookies slice
840var CS = BodyTag.find('footer div.slice_Cookies');
841 if (CS.length === 1) {
842 	CS.find('img').attr('src','/Images/Content/2019/Templates/54496/images/IconClose.png');
843 }
844
845});

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.