1/* 2 Main ChurchInsight template Javascript/JQuery file. 3 WARNING - do not edit this file unless you know exactly what you are doing. 4 Better to use the scriptOverRide.js file to add local changes to a template. 5 If you need advice, contact ChurchInsight Support. 6*/ 7 8// This file runs after the web-page has loaded, as there is a "defer" attribute on the <script> tag in the HTML header. 9// The preloaded JQuery version is V1.10.2. 10 11$(document).ready(function () 12{ 'use strict'; 13 14var UA = navigator.userAgent; 15// IE is deprecated, but lots of people still use it. So we have to make some effort to support it for now. 16// IE works well with a mouse. 17var bOnIE = (UA.indexOf('Trident/') !== -1); // Trident is the rendering engine of IE. 18 19// Custom values set here. Change for a particular customer. 20var SlideShowDefaultButtonText = 'Read more'; 21var bAddDarkenedOverlayForSlideShowCaptions = false; 22 23// #################### Define some useful functions ####################### 24 25// We have to put all functions here, as OSX does not allow functions to be inside if statements. 26 27// function to turn a slice name into a selector reference for the corresponding <section> tag 28function GetSectionTagRef(SliceName) { 29 return 'section.' + SliceName + ' '; 30} 31 32var SectionTag, SectionTags; // will be used to hold required slices 33function SectionTagExists(SliceName) { 34 if (SectionTags.hasClass(SliceName)) { 35 SectionTag = SectionTags.filter(GetSectionTagRef(SliceName)); 36 if (SectionTag.length !== 0) { // at least one slice exists, great. You could have more than one in theory. 37 return true; 38 } 39 } 40 SectionTag = undefined; // remove all data. 41 return false; 42} 43 44function GetRefItem(SectionTag, Ref) { 45 if (typeof Ref === "string") { 46 if (Ref === '') { // allows us to return the section tag itself. 47 return SectionTag; 48 } else { 49 return SectionTag.find(Ref); 50 } 51 } else { 52 return Ref; 53 } 54} 55 56// A function to easily set JQuery toggles. 57// SectionTag is a $ variable. 58function ApplyToggleVisibilityOnClick(SectionTag, ClickRef, ToggleRef, iDelay, bShowToggleItemInitially) { 59 60 var ClickItem = GetRefItem(SectionTag, ClickRef); 61 var ToggleItem = GetRefItem(SectionTag, ToggleRef); 62 63 if (bShowToggleItemInitially) { 64 ToggleItem.show(0); 65 } else { 66 ToggleItem.hide(0); 67 } 68 // Note we add a function here. Since we are only using calling function arguements inside the function argument, 69 // variable scoping correctly works. 70 ClickItem.click(function () { 71 ToggleItem.toggle(iDelay); 72 }); 73} 74 75function ApplyHideOnClick(SectionTag, ClickRef, ToHideRef) { 76 77 var ClickItem = GetRefItem(SectionTag, ClickRef); 78 var ToHideItem = GetRefItem(SectionTag, ToHideRef); 79 80 ClickItem.click(function () { 81 ToHideItem.hide(0); 82 }); 83} 84 85function ApplyToggleClassOnClick(SectionTag, ClickRef, ToggleRef, ClassName) { 86 87 var ClickItem = GetRefItem(SectionTag, ClickRef); 88 var ToggleItem = GetRefItem(SectionTag, ToggleRef); 89 90 // Note we add a function here. Since we are only using calling function arguements inside the function argument, 91 // variable scoping correctly works. 92 ClickItem.click(function () { 93 ToggleItem.toggleClass(ClassName); 94 }); 95} 96 97// function to test if text exists. 98var sAttrText, sAttrText2, sAttrText3, sAttrText4; // Results come back in these variables. 99var DollarTextarea = $("<textarea/>"); // store this once. 100function TextExists(attrText, bSplit) { 101 102 if (attrText === undefined) {return false;} 103 if (attrText === null) {return false;} 104 105 var TextToProcess = attrText.trim(); 106 if (TextToProcess === '') {return false;} 107 108 // decode the text, so that &lt; becomes < etc. 109 // This works by turning into HTML and then turning back into text. 110 if (TextToProcess.indexOf('&') !== -1) { // we could use the .includes('&') method, but it is quite new, so some browsers can't cope. 111 TextToProcess = DollarTextarea.html(TextToProcess).text(); 112 } 113 if (TextToProcess === '') {return false;} 114 115 sAttrText = ''; // set return values to blank. 116 sAttrText2 = ''; 117 sAttrText3 = ''; 118 sAttrText4 = ''; 119 if (bSplit) { 120 var arrSplitText = TextToProcess.split('*'); 121 sAttrText = arrSplitText[0].trim(); 122 if (arrSplitText.length > 1) {sAttrText2 = arrSplitText[1].trim();} 123 if (arrSplitText.length > 2) {sAttrText3 = arrSplitText[2].trim();} 124 if (arrSplitText.length > 3) {sAttrText4 = arrSplitText[3].trim();} 125 } else { 126 sAttrText = TextToProcess; 127 } 128 129 return (sAttrText + sAttrText2 + sAttrText3 + sAttrText4 !== ''); 130} 131
132// Function to hide a column if it contains no images. 133var SystemSlice; 134function HideDivsIfAllEmpty(ColumnClass) { 135 var ImageWrappers = SystemSlice.find('div.' + ColumnClass); 136 if (ImageWrappers.find('img').length === 0) { // have to use find not children, as img tags can be inside <a> tags. 137 ImageWrappers.hide(0); 138 } 139} 140 141// ################### Slice activation functions go here. ######################### 142 143// All slide shows have the same defaults at present. 144var BxDefaultValues = { 145 mode: 'fade', 146 auto: true, 147 pause: 8000, 148 speed: 500, 149 pager: true, 150 controls: true, 151 preloadImages: 'all', 152 touchEnabled: false, 153 adaptiveHeight: true 154}; 155 156var SectionTagBackup; 157function ActivateBxSlider(SliceName,bPreserveSectionTag) { 158 if(bPreserveSectionTag){SectionTagBackup = SectionTag;} 159 if (SectionTagExists(SliceName)) { // check if slice exists, and load into SectionTag if it does 160 161 var bannerSlides = SectionTag.find('div.bannerSlides'); // use a "find" here, as structure of slices varies. 162 var gallery_ul = bannerSlides.children('ul.gallery_ul'); 163 var ImageList = gallery_ul.find('img'); 164 if (ImageList.length === 0) {return;} // No images, so give up. 165 166 // ul.gallery_ul must be displayed before bx-slider can be applied. 167 // So since we hide it while the page was loading, we show it now. 168 bannerSlides.show(0); // show the slice now. It was hidden by CSS. 169 170 if (ImageList.length > 1) { // carry on as normal. 171 gallery_ul.bxSlider(BxDefaultValues); 172 } else { // Just 1 image, so we don't set up the slider, but do some minor adjustments to help the CSS. 173 gallery_ul.css('margin','0px'); 174 var S = '<div class="bx-wrapper"><div class="bx-viewport"></div></div>'; 175 gallery_ul.wrap(S); 176 } 177 178 // Code to enable user defined text to appear over banner slides. 179 ImageList.each(function() { 180 var ThisImg = $(this); 181 if (TextExists(ThisImg.attr('alt'), true)) { // check if there is any alt text. 182 var DarkenedClass = ''; 183 if (bAddDarkenedOverlayForSlideShowCaptions) {DarkenedClass = ' DarkenedOverlay';} 184 var title = '<div class="slideTitle' + DarkenedClass + '">' + sAttrText + '</div>'; 185 // even if the subtitle text is empty, we keep the div for styling reasons. 186 // If there is a long caption, reduce font weight from bold to normal. 187 var FontStyle = ''; 188 if (sAttrText2.length > 100) {FontStyle = ' style="font-weight:400;" ';} 189 var subtitle = '<div class="slideText' + DarkenedClass + '"' + FontStyle + '>' + sAttrText2 + '</div>'; 190 191 var ButtonLink = ''; 192 var ButtonText = sAttrText3; 193 if (ButtonText === '') {ButtonText = SlideShowDefaultButtonText;} 194 if (ButtonText !== '' && ButtonText !== 'none'){ 195 var ButtonColor = sAttrText4; 196 if (TextExists(ThisImg.parent().attr('href'), false)) { // check for href text. NOTE: sAttrTextX values are reset. 197 198 // add button colour if we have some colour data. 199 // Check for a " character, as that will spoil our HTML. 200 if (ButtonColor !== '' && ButtonColor.indexOf('"') === -1) { 201 ButtonColor = ' style="background-color:' + ButtonColor + ' !important;border-color:' + ButtonColor + ' !important;" '; 202 } 203 204 // build the completed button link. 205 ButtonLink = '<a class="slideButton" href="' + sAttrText + '"' + ButtonColor + '>' + ButtonText + '</a>'; 206 } 207 } 208 209 var caption = '<div class="caption">' + title + subtitle + ButtonLink + '</div>'; 210 $(caption).insertAfter(this); 211 } 212 ThisImg.removeAttr('title'); // remove the title attribute so that pop-up text does not appear. 213 }); 214 } 215 if(bPreserveSectionTag){SectionTag = SectionTagBackup;} 216} 217 218// define a function, so we can activate a SlickNav menu in a controlled way. 219var IEDy = 0, bEDopen = false; 220function ActivateMenu(SliceName) { 221 if (SectionTagExists(SliceName)) { // check if slice exists, and load into SectionTag if it does 222 223 var SectionTagRef = GetSectionTagRef(SliceName); 224 var RootMenuDeskTop = SectionTag.find('div.nav-menu').children('ul.root_menu'); 225 226 RootMenuDeskTop.slicknav({ // activate SlickNav for this slice. 227 prependTo: SectionTagRef + '> div.SlickNav_Wrapper', 228 allowParentLinks: true, // Top level items can be links 229 label: '', 230 duration:100, 231 easingOpen:'linear', 232 easingClose:'linear', 233 // Use hex escape characters here. 234 closedSymbol: '', // a logical OR "V" symbol 235 openedSymbol: '', // a nice up pointing ">" symbol 236 duplicate: bDesktopScreenPossible // only need to duplicate if the desktop menus are needed. 237 }); 238 239 var SlickNavLastItem = SectionTag.find('ul.slicknav_nav > li:last-child'); 240 //Add extra links onto the SlickNav menu manually, to replace top-link log-out buttons etc. 241 var ExtraLink_1 = '<li class="ExtraLink Giving">
241<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>'; 242 var ExtraLink_2 = '';//'<li class="ExtraLink ContactUs"><a class="top-link button Login ContactUs" href="/Groups/220185/Contact_Us.aspx">CONTACT US</a></li>'; 243 var ExtraLink_3 = '<li class="ExtraLink SearchOpen"></li>'; 244 $(ExtraLink_2 + ExtraLink_1 + ExtraLink_3).insertAfter(SlickNavLastItem); 245 246 if (bOnTouchDevice && bDesktopScreenPossible) { // have to do more work on menus. 247 248 // Having made the SlickNav menu - delete what we don't want. 249 250 SectionTag.children("div.SlickNav_Wrapper").children("div.slicknav_menu").children('ul.slicknav_nav').find('li.SlickNavNotNeeded').remove(); 251 252 // deactivate the top level <a> tag in the desk-top version so touch-screens work correctly. 253 // The link goes nowhere, but retains all the styling. 254 RootMenuDeskTop.children("li.has_sub_menu").children('a').removeAttr("href"); 255 } 256 257 // Add a close menu icon into slickNav. 258 var SlickNavIcon = SectionTag.find('span.slicknav_icon'); 259 $('<div class="SlickNavCloseIcon"></div>').insertAfter(SlickNavIcon); 260 261 // apply all the visibility on-clicks to make the menu slice work. 262 263 // Find some commonly used items. 264 //var SearchOverlay = SectionTag.find("div.search-overlay"); 265 var SlickNavBtn = SectionTag.find("a.slicknav_btn"); 266 var Mask = BodyTag.find('div.MobileMenuMask'); 267 268 //ApplyToggleVisibilityOnClick(SectionTag, "li.ExtraLink.SearchOpen", SearchOverlay, 0, false); 269 //ApplyToggleVisibilityOnClick(SectionTag, "div.top-link-wrapper a:last-child", SearchOverlay, 0, false); 270 //ApplyHideOnClick(SectionTag, "img.search-close", SearchOverlay); 271 //ApplyHideOnClick(undefined, SlickNavBtn, SearchOverlay); 272 // Toggles for menu-bars and menu-close icons 273 ApplyToggleVisibilityOnClick(undefined, SlickNavBtn, SlickNavIcon, 0, true); // no delay on the toggle. 274 ApplyToggleVisibilityOnClick(SectionTag, SlickNavBtn, "div.SlickNavCloseIcon", 0, false); // no delay on the toggle. 275 ApplyToggleVisibilityOnClick(undefined, SlickNavBtn, Mask, 0, false); // no delay on the toggle. 276 ApplyToggleClassOnClick(SectionTag, SlickNavBtn, '', 'SlickNavFullWidth'); 277 SlickNavBtn.click(function(){ 278 if(!bEDopen){ 279 IEDy = window.pageYOffset; 280 window.scrollTo(0,0); 281 } else { 282 window.scrollTo(0,IEDy); 283 } 284 bEDopen = !bEDopen; 285 }); 286 // Link white-eye-glass to hidden search button. 287 //var HiddenSearchBox = SearchOverlay.find('input.button'); 288 //SearchOverlay.find('img.search-EyeGlass').click(function(){HiddenSearchBox.click();}); // set up the click. 289 290 // Need autocomplete="off" to be added to the search box <input> tag. 291 // This stops horrible browser autocomplete text from appearing. 292 //SearchOverlay.find('input.text').attr("autocomplete","off"); 293 294 } 295} 296 297function ActivateArticleList4(SliceName) { // SliceName is an object, not a string. 298 299 // Get the summaries 300 var Summarys = SliceName.find('div.articleListSummary span'); 301 302 // Create the links at the bottom of the article cards. 303 var j=0, iBookShelfHidden=0; 304 SliceName.find('div.articleListTitle a').each(function () { 305 var ThisAtag = $(this); 306 var OuterDiv = ThisAtag.parent().parent(); 307 var titleText = ThisAtag.text().trim().toLowerCase(); 308 if (titleText.endsWith(' bookshelf')) { 309 OuterDiv.remove(); // remove the whole card. 310 iBookShelfHidden++; 311 } else { 312 var titleLink = ThisAtag.attr("href"); 313 var articleListLink = OuterDiv.children('.articleListLink'); 314 // See if we have new link text. 315 if (TextExists(Summarys.eq(j).text(), true)) { 316 if(sAttrText.toLowerCase() === titleText){Summarys.eq(j).parent().hide();} // hide summary if exactly the same as title. 317 if (sAttrText2 !== '') { 318 articleListLink.text(sAttrText2); 319 } 320 } 321 articleListLink.wrapInner('<a href="' + titleLink + '">'); 322 // Check the tags to see if we need to put in an image. 323 if(TemplateType.startsWith('Resources')) { 324 var ImageURL = 'FileTypeUNKNOWN.png'; 325 var Tags = OuterDiv.children('.articleListTags'); 326 if (Tags.length === 1) { 327 var TagText = Tags.text().trim(); 328 if (TagText === 'pdf' || TagText.startsWith('pdf, ') || TagText.indexOf(' pdf, ') !== -1 || TagText.endsWith(', pdf')) {ImageURL = 'FileTypePDF.png';} 329 else if (TagText === 'doc' || TagText.startsWith('doc, ') || TagText.indexOf(' doc, ') !== -1 || TagText.endsWith(', doc')) {ImageURL = 'FileTypeDOC.png';} 330 else if (TagText === 'ppt' || TagText.startsWith('ppt, ') || TagText.indexOf(' ppt, ') !== -1 || TagText.endsWith(', ppt')) {ImageURL = 'FileTypePPT.png';} 331 else if (TagText === 'xls' || TagText.startsWith('xls, ') || TagText.indexOf(' xls, ') !== -1 || TagText.endsWith(', xls')) {ImageURL = 'FileTypeXLS.png';} 332 else if (TagText === 'zip' || TagText.startsWith('zip, ') || TagText.indexOf(' zip, ') !== -1 || TagText.endsWith(', zip')) {ImageURL = 'FileTypeZIP.png';} 333 334 else if (TagText === 'vid' || TagText.startsWith('vid, ') || TagText.indexOf(' vid, ') !== -1 || TagText.endsWith(', vid')) {ImageURL = 'FileTypeVIDEO.png';} 335 //else if (TagText === 'dvd' || TagText.startsWith('dvd, ') || TagText.indexOf(' dvd, ') !== -1 || TagText.endsWith(', dvd')) {ImageURL = 'FileTypeBUY.png';} 336 else if (TagText === 'free' || TagText.startsWith('free, ') || TagText.indexOf(' free, ') !== -1 || TagText.endsWith(', free')) {ImageURL = 'FileTypeFREE.png';} 337 else if (TagText === 'aud' || TagText.startsWith('aud, ') || TagText.indexOf(' aud, ') !== -1 || TagText.endsWith(', aud')) {ImageURL = 'FileTypeAUDIO.png';} 338 else if (TagText === 'buy' || TagText.startsWith('buy, ') || TagText.indexOf(' buy, ') !== -1 || TagText.endsWith(', buy')) {ImageURL = 'FileTypeBUY.png';} 339 } 340 OuterDiv.children('.articleListImage').hide(); // hide any existing image 341 var H = '<div class="articleListImage"><a href="' + titleLink + '"><img src="/Images/Content/2019/Templates/54496/images/' + ImageURL + '"></a></div>'; 342 $(H).prependTo(OuterDiv); 343 } 344 } 345 j++; 346 }); 347console.log('iBookShelfHidden: ' + iBookShelfHidden); 348 349 Summarys.each(function () { 350 var ThisSummary = $(this); 351 var S = ThisSummary.text(); 352 if (TextExists(S, true)) { 353 sAttrText = sAttrText.replace(/\\/g,'<br>'); 354 if (S !== sAttrText) { 355 ThisSummary.html(sAttrText); 356 } 357 } 358 }); 359} 360 361function ActivateBlockImages(SliceName) { 362 if (SectionTagExists(SliceName)) { // check if slice exists, and load into SectionTag if it does 363 SectionTag.find("div.image_blocks img" ).each(function() { 364 if (TextExists($(this).attr('alt'), true)) { // check if there is any alt text. 365 var cardGridCaption = '<div class="image_block_title_wrapper"><div class="image_block_title">' + sAttrText + '</div><div class="image_block_text">' + sAttrText2 + '</div></div>'; 366 $(cardGridCaption).insertAfter( this ); 367 } 368 $(this).removeAttr('title'); // remove the title attribute so that pop-up text does not appear. 369 }); 370 } 371} 372 373// General Code to find a group notes value 374function GetGroupNotesValue(NoteName,bIsLink) { 375 var GNames = SectionTag.find('span.groupnotes_name');
376 var iGN = 0, bFinished = false, NN = NoteName + ':', NN2 = NoteName + ' (?):'; 377 GNames.each(function() { // If 2 notes have the same name, then the value of the first is returned. 378 if (!bFinished) { 379 var ThisSpan = $(this); 380 var S = ThisSpan.text(); 381 if(S === NN || S === NN2){ 382 bFinished = true; 383 } else { 384 iGN++; 385 } 386 } 387 }); 388 if (bFinished) { 389 var GValue = SectionTag.find('span.groupnotes_value').eq(iGN); 390 if (bIsLink) { 391 return GValue.find('a').attr('href'); 392 } else { 393 return GValue.text(); 394 } 395 } 396 return ''; 397} 398 399var TemplateType = 'About Us'; 400var ArticleCardDisplay = 'Full Cards'; 401var ResourceSort = 'Date Ascending'; 402function ActivateBannerImage(SliceName) { 403 if (SectionTagExists(SliceName)) { // check if slice exists, and load into SectionTag if it does 404 405 var bImageApplied = false; 406 407 if (TextExists(GetGroupNotesValue('Banner Image',true), false)) { 408 409 SectionTag.css('background-image','url(' + sAttrText + ')'); 410 bImageApplied = true; 411 412 // background image applied, so add group name, if available. 413 if (TextExists($('head meta[name="Group Name"]').attr('content'), false)) { 414 SectionTag.find('h1').text(sAttrText); 415 } else if (TextExists(BodyTag.find('section.slice_content_page nav div.group_nav_selected > a').text(), false)) { 416 // Try and get name from side-bar GroupNav - see line above 417 SectionTag.find('h1').text(sAttrText); 418 } else if (TextExists($('head meta[name="og:title"]').attr('content'), false)) { 419 // Try the article name. 420 SectionTag.find('h1').text(sAttrText); 421 SectionTag.find('h1').addClass('SmallerFont'); 422 } 423 } 424 // While we are here, get the Template Type 425 var S = GetGroupNotesValue('Template Mode',false); 426 if (S !== '') { 427 TemplateType = S; 428 if(TemplateType !== 'About Us'){ 429 BodyTag.addClass(TemplateType.replace(' + ','').replace(' ','').replace(' ','')); 430 } 431 } 432 433 S = GetGroupNotesValue('Article Cards Mode',false); 434 if (S !== '') {ArticleCardDisplay = S;} 435 436 S = GetGroupNotesValue('Resource Article Sort Mode',false); 437 if (S !== '') {ResourceSort = S;} 438 439 if (!bImageApplied) { // Didn't find background image, so hide the whole slice. 440 SectionTag.hide(); 441 if (SectionTagExists('slice_content_page')) { // add a grey border to the content slice. 442 SectionTag.addClass('AddTopBorder'); 443 } 444 } 445 } 446} 447 448function ActivateRA() { // Related Articles - Need to build the HTML. 449 var RA = BodyTag.find('section.sliceRelatedArticles'); 450 if (RA.length > 0) { 451 if (RA.find('li.links').length > 0) { // check if there is any content 452 453 // Work out what links we have. 454 var Spans = RA.find('span.LinkHeading'); 455 var S = Spans.eq(0).text().trim(); 456 var bArticles = (S === 'Related Articles'); 457 var bFiles = (S === 'Files' || Spans.eq(1).text().trim() === 'Files'); 458 459 var ULs = RA.find('ul'); 460 461 var ArticleBoxHTML = ''; 462 if (bArticles) { 463 ArticleBoxHTML = '<div class="RX_ArticleBox"><div>Articles:</div><ul>' + ULs.eq(0).html() + '</ul></div>'; 464 } 465 466 var FileBoxHTML = ''; 467 if (bFiles) { 468 if (bArticles) {S = ULs.eq(1).html();} else {S = ULs.eq(0).html();} 469 FileBoxHTML = '<div class="RX_FileBox"><div>Files:</div><ul>' + S + '</ul></div>'; 470 } 471 472 if(ArticleBoxHTML !== '' && FileBoxHTML !== ''){ 473 ArticleBoxHTML.replace('RX_ArticleBox','RX_ArticleBox HalfWidth'); 474 FileBoxHTML.replace('RX_FileBox','RX_FileBox HalfWidth'); 475 } 476 477 var H ='<div class="RA_TitleWrapper"><div class="RA_Title">Related Content</div><img src="/Images/Content/2019/Templates/54496/images/RelatedContentBlock.png"></div><div class="RA_LinksBox">' + ArticleBoxHTML + FileBoxHTML + '</div>'; 478 RA.html(H); 479 480 if (bFiles) { 481 H = $('<img src="/Images/Content/2019/Templates/54496/images/IconFile.png">'); 482 H.prependTo(RA.find('div.RX_FileBox a')); 483 } 484 485 // Clean up the HTML 486 RA.find('a').each(function(){ 487 var A = $(this); 488 var href = A.attr('href').trim(); 489 A.attr('href',href); 490 if (href.startsWith('/P')) {A.attr('target','_blank');} 491 }); 492 493 RA.show(); 494 } 495 } 496} 497 498 function ReduceArticleHref (S,bCheckLongHref) { 499 var href = S, iSlash; 500 if (bCheckLongHref && !href.startsWith('/Articles/')) { 501 href = href.replace('http://',''); 502 href = href.replace('https://',''); 503 iSlash = href.indexOf('/'); 504 href = href.substring(iSlash); 505 if(!href.startsWith('/Articles/')){return '';} 506 } 507 iSlash = href.indexOf('/',10); 508 href = href.substring(0, iSlash + 1); 509 return href; 510 } 511
512function DeDupeArticleList() { 513 var AB_As = SectionTag.find('div.main-content div.ArticleBody a'); 514 var CP_AL = SectionTag.find('div.main-content div.ContentPageArticleList div.ContentPageAL a'); 515 // Make a fast array of CP_AL links 516 var i = 0, arr = []; 517 CP_AL.each(function () { 518 arr[i] = ReduceArticleHref($(this).attr('href'), false); 519 i++; 520 }); 521 var j = 0, k, arr2 = []; 522 AB_As.each(function () { 523 var href = ReduceArticleHref($(this).attr('href'), true); 524 if (href !== '') { 525 for (k = 0; k < i; k++) { 526 if (href === arr[k]) { 527 arr2[j] = k; 528 j++; 529 } 530 } 531 } 532 }); 533 // add in any related links. 534 SectionTag.find('section.sliceRelatedArticles div.RX_ArticleBox a').each(function (){ 535 var href = ReduceArticleHref($(this).attr('href'), false); 536 for (k = 0; k < i; k++) { 537 if (href === arr[k]) { 538 arr2[j] = k; 539 j++; 540 } 541 } 542 }); 543 // hide the dupes. 544 var iRemoved=0,bMask = []; // use a mask so we don't try and delete the same thing twice etc. 545 for (k = 0; k < i; k++) { // there will be < i articles on the page 546 bMask[k] = true; 547 } 548 for (k = 0; k < j; k++) { 549 var l = arr2[k]; 550 if(bMask[l]){ 551 CP_AL.eq(l).parent().parent().remove(); 552 bMask[l] = false; 553 iRemoved++; 554 } 555 } 556 console.log('Dupes removed: ' + iRemoved); 557 // If some links left, show whole slice. 558 CP_AL = SectionTag.find('div.main-content div.ContentPageArticleList'); 559 if (CP_AL.find('div.ContentPageAL a').length > 0) { 560 if(TemplateType === 'About Us + Blog'){CP_AL.find('div.ContentPageAL').addClass('Blog');} 561 CP_AL.show(); 562 } 563} 564 565function TurnGalleryIntoArticleList(SliceName) { 566 if (SectionTagExists(SliceName)) { // check if slice exists, and load into SectionTag if it does 567 var OuterDiv = SectionTag.find('div.article_cards.LandingGallery'); // module CSS class must be this 568 OuterDiv.find('li.gallery_li a').each(function () { 569 var ThisAtag = $(this); 570 var titleLink = ThisAtag.attr("href"); 571 var Target = ThisAtag.attr("target"); 572 var ThisImg = ThisAtag.children('img'); 573 TextExists(ThisImg.attr('alt'), true); 574 var Div1 = '<div class="articleListImage"><a href="' + titleLink + '" target="' + Target + '"><img src="' + ThisImg.attr('src') + '" alt="Summary Image"/></a></div>'; 575 var Div2 = '<div class="articleListTitle"><a href="' + titleLink + '" target="' + Target + '">' + sAttrText + '</a></div>'; 576 //if (sAttrText3 !== '') {sAttrText2 = sAttrText2 + '*' + sAttrText3;} 577 var Div3 = ''; //if (sAttrText2 !== ''){Div3 = '<div class="articleListSummary"><span>' + sAttrText2 + '</span></div>';} 578 var Div4 = ''; //'<div class="articleListLink">Read more</div>'; 579 var S = '<div>' + Div1 + Div2 + Div3 + Div4 + '</div>'; 580 $(S).appendTo(OuterDiv); 581 }); 582 } 583} 584 585// ########################## Check various conditions ############################# 586 587var bOnTouchDevice = ('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0); 588var iDeskTopWidth = 992; 589var iMobileScreenAllowence = 64; // Because of other stuff on a screen, you have to assume the browser window could get bigger on a rotation. 590var bDesktopScreenPossible = ((screen.width + iMobileScreenAllowence) >= iDeskTopWidth || (screen.height + iMobileScreenAllowence) >= iDeskTopWidth); 591 592var BodyTag = $('body'); 593var bOnSystemPopupPage = BodyTag.hasClass('system_popup') || (window.location.href.toLowerCase().indexOf('popup=yes') !== -1); 594var bUserLoggedIn = BodyTag.hasClass('logged_in_user'); 595 596SectionTags = BodyTag.find('section'); // Store all the section tags to speed up later code. 597var bOnContentPage = SectionTags.hasClass('slice_content_page'); 598var bOnSystemPage = SectionTags.hasClass('slice_system_page'); 599var bOnHomePage = SectionTags.hasClass('slice_image_blocks_4'); 600var bOnLandingPage = SectionTags.hasClass('LandingPage'); 601 602// Sort out IE stuff. 603if(bOnIE){ 604 BodyTag.addClass('OnIE'); 605 var S = '<div class="IEWarning">Unfortunately this website does not display correctly on the IE11 browser. We advise the use of Chrome, Edge, Safari, or FireFox.</div>'; 606 $(S).appendTo(BodyTag); 607}
608 609if (bOnContentPage || bOnLandingPage) { 610 ActivateBannerImage('slice_BannerImage'); 611} 612 613// Activate the slide shows first as they are usually near the top of the visible screen. 614if (bOnHomePage) { 615 616 // ############################################################## 617 // # js for Slide Shows slices. We use BX-slider V4.2.5 618 // ############################################################## 619 620 // The slide-shows are hidden via CSS when the page first loads, to give a smoother page-load experience. 621 // All slide-show CI modules must have a class "bannerSlides" defined within them. 622 623 // Activate all the slide-shows. Do in sensible order, so any visible ones are done first. 624 ActivateBxSlider('slice_SlidesFullWidth',false); 625} 626 627// ####################################### 628// # Menu data changes 629// ####################################### 630 631// We make the required adjustments to the one set of menu HTML on the page, before cloning it and activating all the copies. 632 633var ulModuleRootMenu = BodyTag.find('ul.root_menu'); 634var bMenuPresent = (ulModuleRootMenu.length !== 0); 635if (bMenuPresent) { 636 637 // Set up the search icon in the search box. 638 if(bDesktopScreenPossible){ 639 var DeskTopSearchBox = BodyTag.find('header div.top-link-wrapper div.search-form'); 640 var HiddenSearchBox = DeskTopSearchBox.find('input.button'); 641 DeskTopSearchBox.find('input.text').attr("autocomplete","off"); 642 $('<img alt="Icon" src="/Images/Content/2019/Templates/54496/images/IconEyeGlassBlue.png">').appendTo(DeskTopSearchBox); 643 DeskTopSearchBox.find('img').click(function(){HiddenSearchBox.click();}); // set up the click. 644 } 645 646 // Only keep some of the top-level menu items. 647 ulModuleRootMenu.find('li.menu_item_level_1').each(function() { 648 var ThisLi = $(this); 649 var Ahref = ThisLi.children('a').attr('href'); 650 if ( 651 !Ahref.startsWith('/Groups/213223/') && 652 !Ahref.startsWith('/Groups/220180/') && 653 !Ahref.startsWith('/Groups/220181/') && 654 !Ahref.startsWith('/Groups/220184/') && 655 !Ahref.startsWith('/Groups/220185/') && // Contact Us 656 !Ahref.startsWith('/Groups/220182/') && // Latest Updates 657 !Ahref.startsWith('/MyArea/') 658 ) { 659 ThisLi.remove(); 660 } 661 }); 662 663 /* remove sub menus from Home */ 664 // This assumes that the home menu is the first item with a sub menu. 665 var HomeMenuLi = ulModuleRootMenu.children('li:first-child'); 666 HomeMenuLi.children('ul').remove(); 667 HomeMenuLi.removeClass('has_sub_menu'); // remove class 668 //HomeMenuLi.children('a').attr("href","/"); // replace link with base domain reference, not a group reference. 669 670 // remove copies of 1st item elements in dropdown sub-menu. 671 ulModuleRootMenu.find('li.menu_item_level_2:first-child').each(function() { 672 673 var ThisLi = $(this); 674 if(ThisLi.children("a[href^='/MyArea/']").length === 0) { // only if not a link into /MyArea/... 675 676 if(ThisLi.siblings().length === 0) { // no other <li> so it is the only entry 677 var ul = ThisLi.parent(); 678 ul.parent().removeClass('has_sub_menu'); // remove class from the <li> at the level above 679 ul.remove(); // delete whole parent <ul> 680 681 } else { 682 if (bOnTouchDevice && bDesktopScreenPossible) { 683 // On a touch device, the copies of the level one links at the 2nd level have to be kept for the desktop menus. 684 // But in the SlickNav menus, these 2nd level links are not needed. 685 // So we mark the items so we can delete them later, after data is copied into the SlickNav menu. 686 ThisLi.addClass('SlickNavNotNeeded'); // Mark the 2nd level <li> tag. 687 } else { 688 // Not on a touch screen, so Desktop and SlickNav menus will be the structurally the same. 689 ThisLi.remove(); // so just remove this <li> tag 690 } 691 } 692 } 693 }); 694 695 // ####################################### 696 // # SlickNav menus V1.0.10 697 // ####################################### 698 699 ActivateMenu('slice_Header_L'); 700 701 // Set up Search box inside SlickNav 702 var DeskTopSearchBoxM = BodyTag.find('header div.SlickNav_Wrapper div.search-overlay'); 703 var LIs = BodyTag.find('header div.SlickNav_Wrapper ul.slicknav_nav li.ExtraLink.SearchOpen'); 704 DeskTopSearchBoxM.appendTo(LIs); 705 var HiddenSearchBoxM = DeskTopSearchBoxM.find('input.button'); 706 DeskTopSearchBoxM.find('input.text').attr("autocomplete","off"); 707 $('<img alt="Icon" src="/Images/Content/2019/Templates/54496/images/IconEyeGlassBlue.png">').appendTo(DeskTopSearchBoxM); 708 DeskTopSearchBoxM.find('img').click(function(){HiddenSearchBoxM.click();}); // set up the click. 709 710} // end of if bNeedMenus 711 712// Here do things ONLY needed on a home page. 713if (bOnHomePage) { 714 715 // Article list - 4 in a row on desktop 716 if (SectionTagExists('slice_WelcomeArticles')) { // check if slice exists, and load into SectionTag if it does 717 ActivateArticleList4(SectionTag); 718 } 719 720 // image blocks 721 ActivateBlockImages('slice_image_blocks_4'); 722 723} else if (bOnContentPage) { 724 725 if (SectionTagExists("slice_content_page")) { 726 727console.log('TemplateType: ' + TemplateType);
728console.log('ArticleCardDisplay: ' + ArticleCardDisplay); 729 730 // Check if article is empty - if so, then show the replacement of 6 article cards. 731 var CA = SectionTag.find('div.CurrentArticle'); 732 var RA = SectionTag.find('div.ReplacementArticle'); 733 var bHaveCurrentArticle = ( (CA.length === 1) && (CA.find('div#bookshelfWrapper').length === 0) ); 734console.log('bHaveCurrentArticle: ' + bHaveCurrentArticle); 735 if (bHaveCurrentArticle) { 736 if (TemplateType === 'About Us' || TemplateType === 'About Us Purple') {ActivateBxSlider('slice_SlidesFullWidth',true);} 737 if (TemplateType === 'Baptist Times') {SectionTag.find('div.TaggedAL').remove();} 738 RA.remove(); // delete this so all the dupes go. 739 ActivateRA(); // Build Related Articles - do in all modes - as we have a current article. 740 } else { 741 CA.hide(); 742 // Look for a BT home-mission article 743 if (TemplateType === 'Baptist Times') { 744 // First check if the home-mission stories article is already in the list of 6 745 var bFound = false; 746 var AC = RA.find('div.article_cards'); 747 var RAs = AC.children(); 748 RAs.each(function(){ 749 var S = $(this).find('div.articleListTitle a').text().toLowerCase(); 750 if(S.endsWith('home mission stories')){bFound = true;} 751 }); 752 if(!bFound){ 753 var TaggedAL = SectionTag.find('div.TaggedAL div.article_cards').children(); 754 if (TaggedAL.length === 1 ) { 755 // Need to move this article into the group of 6 756 if(RAs.length === 6){RAs.eq(5).remove();} 757 TaggedAL.prependTo(AC); 758 console.log('Home Mission Stories article slotted in.'); 759 } 760 } 761 } 762 SectionTag.find('div.TaggedAL').remove(); // delete this as well. You can only have a TaggedAL to go with an article. 763 if (RA.find('div.article_cards').children().length > 0) { 764 RA.show(); 765 console.log('ReplacementArticle current-group card list showing.'); 766 } else { // even the replacement of 6 article cards is empty, so show the group-based cards. 767 SectionTag.find('div.ReplacementArticleB').show(); 768 console.log('ReplacementArticleB group list showing.'); 769 } 770 } 771 772 // HACK 773 var S = location.href; 774 if(S.indexOf('220492') !== -1){SectionTag.find('div.ReplacementArticleB').show();} 775 776 // Look for article_cards 777 var AB = SectionTag.find('div.ArticleBody'); 778 var bArcticleCards = (AB.find('div.article_cards').length > 0); 779 if (bArcticleCards) { 780 ActivateArticleList4(AB); // do in all modes. 781 SectionTag.children('div.container').addClass('Wide'); 782 } 783 784 if (TemplateType.startsWith('About Us')) { 785 // See if the Tagged AL has anything in it. 786 var TaggedAL = SectionTag.find('div.TaggedAL div.article_cards'); 787 if (TaggedAL.length === 1 ) { 788 // great, we are showing the tagged AL. 789 console.log('Tagged AL showing.'); 790 } else if (TemplateType === 'About Us + Blog') { 791 DeDupeArticleList(); // there is no tagged list, so show this list instead. 792 console.log('Blog AL showing.'); 793 } 794 /* 795 // Check if we have a SafeGuarding Page. 796 var SG = SectionTag.find('div.ArticleBody div.SafeGuardFlexBox'); 797 if(SG.length > 0){ 798 SectionTag.addClass('FullWidth'); 799 } else { 800 SectionTag.find('aside div.ContentPageImage.Advert').show(); 801 } 802 */ 803 SectionTag.find('aside div.ContentPageImage.Advert').show(); 804 805 // Look for events. 806 var E = SectionTag.find('aside div.SideEventsList'); 807 if (E.children('div.EventModule').children().length > 0) { 808 E.show(); 809 } 810 811 } else if (TemplateType === 'Baptist Times') { 812 // DeDupe the article-list. 813 DeDupeArticleList(); 814 SectionTag.find('aside div.ContentPageImage').show(); 815 816 if (bHaveCurrentArticle && !bArcticleCards) { 817 // Do the Facebook and Twitter share buttons. 818 var myURL = encodeURI(window.location.href); 819 var SMS = SectionTag.find('section.SocialMediaShare'); // 2 of these 820 821 var FacebookButton = SMS.find('a.FaceBookShare'); 822 var FacebookShareURL = 'https://www.facebook.com/sharer/sharer.php?u=' + myURL; 823 FacebookButton.attr('href', FacebookShareURL); 824 825 var TwitterButton = SMS.find('a.TwitterShare'); 826 var TwitterText = 'Please%20read%20this:'; 827 var Meta = $('head meta[name="og:title"]'); 828 if (Meta.length === 1) { 829 TwitterText = Meta.attr('content'); 830 TwitterText = encodeURI(TwitterText); 831 } 832 var TwitterShareURL = 'https://twitter.com/intent/tweet?text=' + TwitterText + '&via=BaptistTimes&url=' + myURL; 833 TwitterButton.attr('href', TwitterShareURL); 834 SMS.show(); 835 } 836 837 } else if (TemplateType.startsWith('Resources')) { 838 var CPS = BodyTag.find('section.ContentPageSearch'); 839 CPS.show(); 840 CPS = CPS.find('div.search-overlay'); 841 CPS.find('input.text').attr("autocomplete","off"); 842 // Link white-eye-glass to hidden search button. 843 var HiddenSearchBoxR = CPS.find('input.button'); 844 CPS.find('img.search-EyeGlass').click(function(){HiddenSearchBoxR.click();}); // set up the click. 845 // Add an extra class, so we can re-format PDF based articles. 846 AB.addClass('Resources');
847 var DMI = AB.find('div.mediaInfo'); 848 var FileText = DMI.text().trim().toLowerCase(); 849 if(FileText.indexOf('file type: word') !== -1 || FileText.indexOf('file type: doc') !== -1){ 850 DMI.children('div.mediaButtons').addClass('FileWord'); 851 } else if (FileText.indexOf('file type: pdf') !== -1){ 852 DMI.children('div.mediaButtons').addClass('FilePDF'); 853 } else if (FileText.indexOf('file type: xls') !== -1){ 854 DMI.children('div.mediaButtons').addClass('FileXLS'); 855 } else if (FileText.indexOf('file type: ppt') !== -1){ 856 DMI.children('div.mediaButtons').addClass('FilePPT'); 857 } else if (FileText.indexOf('file type: buy') !== -1){ 858 DMI.children('div.mediaButtons').addClass('FileBUY'); 859 } else if (FileText.indexOf('file type: zip') !== -1){ 860 DMI.children('div.mediaButtons').addClass('FileZIP'); 861 } else if (FileText.indexOf('file type: audio') !== -1){ 862 DMI.children('div.mediaButtons').addClass('FileAUDIO'); 863 } else if (FileText.indexOf('file type: free') !== -1){ 864 DMI.children('div.mediaButtons').addClass('FileFREE'); 865 } else if (FileText.indexOf('file type: video') !== -1){ 866 DMI.children('div.mediaButtons').addClass('FileVIDEO'); 867 } else { 868 DMI.children('div.mediaButtons').addClass('FileUNKNOWN'); 869 } 870 //console.log(AB.find('div.mediaInfo').text()); 871 } 872 873 // code to try and make content images work on mobile phones. Set max-width css property is if has not already been set. 874 // If width and height attributes are both set, then the image is compressed horizontally, but that is still better than it overflowing. 875 if (bHaveCurrentArticle) { 876 var ContentImages = SectionTag.find('div.ArticleBody img'); 877 ContentImages.each(function() { 878 var Img = $(this); 879 if (Img.css('max-width') === 'none') { 880 Img.css('max-width','100%'); 881 } 882 }); 883 } 884 } 885 886} else if (bOnLandingPage) { 887 888 console.log('TemplateType: ' + TemplateType); 889 console.log('ArticleCardDisplay: ' + ArticleCardDisplay); 890 891 if (TemplateType === 'Baptist Times') { 892 TurnGalleryIntoArticleList('slice_WelcomeArticles'); 893 } 894 895 var WA; 896 // Main Article list 897 if (SectionTagExists('slice_WelcomeArticles')) { // check if slice exists, and load into SectionTag if it does 898 ActivateArticleList4(SectionTag); 899 if (ArticleCardDisplay !== 'Full Cards') { 900 SectionTag.addClass('TitlesOnly'); 901 } 902 WA = SectionTag; 903 } 904 905 var CPS = BodyTag.find('section.ContentPageSearch.LandingPage'); 906 var bHasArticle = (CPS.find('div.ArticleBody').length > 0); 907 console.log('bHasTopArticle: ' + bHasArticle); 908 909 if (TemplateType.startsWith('About Us')) { 910 if(bHasArticle) { 911 CPS.addClass('White').addClass('Narrow'); 912 ActivateBxSlider('slice_SlidesFullWidth',true); 913 } else { 914 CPS.hide(); 915 } 916 917 // Show the "Landing2019" tagged list, hide the normal St. Alfege one. 918 WA.find('div.article_cards').hide(); 919 //WA.find('div.article_cards.LandingTagged').css('display','flex'); 920 var LG = WA.find('div.article_cards.LandingTagged'); 921 console.log(location.pathname); 922 if(location.pathname.startsWith('/Groups/371309/')){LG.addClass('RowReverse');} 923 LG.css('display','flex'); 924 WA.find('div.ReplacementLanding.GroupCards').hide(); // Don't ever need this in "About Us" mode. 925 console.log('Showing "Landing2019" tagged article list.'); 926 927 } else if (TemplateType === 'Baptist Times') { 928 if(bHasArticle) { 929 CPS.addClass('White'); 930 ActivateBxSlider('slice_SlidesFullWidth',true); 931 } else { 932 CPS.hide(); 933 } 934 WA.addClass('Narrow'); 935 936 // Show the "Landing2019" tagged list, hide the normal St. Alfege one. 937 WA.find('div.article_cards').hide(); 938 WA.find('div.article_cards.LandingGallery').css('display','flex'); 939 WA.find('div.ReplacementLanding.GroupCards').hide(); // Don't ever need this in "Baptist Times" mode. 940 console.log('Showing Landing-page gallery.'); 941 942 /*
943 var ChildGroupList = WA.find('div.ReplacementLanding'); 944 var bLeafNode = (ChildGroupList.find('li').length === 0); 945 console.log('bLeafNode: ' + bLeafNode); 946 if (!bLeafNode) { 947 ChildGroupList.css('display','flex'); 948 // Need to hide all child-group articles from the article-list, or else it looks too cluttered. 949 WA.find('div.article_cards').hide(); 950 WA.find('div.article_cards.NoChildGroups').css('display','flex'); 951 console.log('Showing Group List + articles in current group only.'); 952 } 953 */ 954 955 } else if (TemplateType.startsWith('Resources')) { 956 957 WA.addClass('White'); 958 WA.find('div.BreadCrumbs').show(); 959 960 if(TemplateType !== 'Resources (Simple)'){ 961 var ChildGroupList = WA.find('div.ReplacementLanding'); 962 var bLeafNode = (ChildGroupList.find('div.GroupNavTitle').length === 0); 963 console.log('bLeafNode: ' + bLeafNode); 964 if (!bLeafNode) { 965 ChildGroupList.css('display','flex'); 966 // Need to hide all child-group articles from the article-list, or else it looks too cluttered. 967 WA.find('div.article_cards').hide(); 968 WA.find('div.article_cards.NoChildGroups').css('display','flex'); 969 } else { 970 // Sort cards into the right order. 971 console.log("ResourceSort: " + ResourceSort); 972 if(ResourceSort === "Date Ascending"){ // Reverse sort what we have. 973 var i=0; 974 var AC = WA.find('div.article_cards').eq(0); // first div.article_cards only 975 AC.children().each(function(){ 976 if(i > 0) { // skip the first. 977 var T = $(this); 978 T.prependTo(AC); 979 } 980 //console.log(i); 981 i++; 982 }); 983 } else if(ResourceSort === "Title A-Z" || ResourceSort === "Title Z-A"){ 984 var i=0; 985 var AC = WA.find('div.article_cards').eq(0); // first div.article_cards only 986 var ACC = AC.children(); 987 var arr=[], arr2=[]; 988 var S; 989 ACC.each(function(){ 990 S = $(this).find('div.articleListTitle a').text().trim().toLowerCase(); 991 // Attempt to sort numbers in an intelligent way. 992 S = S.replace('10','A0'); 993 S = S.replace('11','A1'); 994 S = S.replace('12','A2'); 995 S = S.replace('13','A3'); 996 S = S.replace('14','A4'); 997 S = S.replace('15','A5'); 998 S = S.replace('16','A6'); 999 S = S.replace('17','A7'); 1000 S = S.replace('18','A8'); 1001 S = S.replace('19','A9'); 1002 S = S.replace('20','B0'); 1003 S = S.replace('21','B1'); 1004 S = S.replace('22','B2'); 1005 S = S.replace('23','B3'); 1006 S = S.replace('24','B4'); 1007 S = S.replace('25','B5'); 1008 S = S.replace('26','B6'); 1009 S = S.replace('27','B7'); 1010 S = S.replace('28','B8'); 1011 S = S.replace('29','B9'); 1012 arr[i] = S; 1013 arr2[i] = arr[i]; 1014 i++; 1015 }); 1016 var j = i; // number of elements in arr 1017 arr2.sort(); // sort this one. 1018 if(ResourceSort === "Title Z-A"){arr2.reverse();} 1019 //console.log(arr); 1020 //console.log(arr2.sort()); 1021 // Loop over sorted array in reverse order 1022 for(i = j; i > 0; i--){ 1023 for(var k = j; k > 0; k--){ 1024 if(arr2[i-1] === arr[k-1]){ // shift indexes by -1 1025 ACC.eq(k-1).prependTo(AC); 1026 } 1027 } 1028 //console.log(i); 1029 } 1030 } 1031 // Make sure any article with "Index" in its name, is at the start of the list. 1032 var AC = WA.find('div.article_cards').eq(0); // first div.article_cards only 1033 var ACC = AC.children(); 1034 var bKeepGoing = true; 1035 ACC.each(function(){ 1036 if(bKeepGoing){ 1037 var T = $(this); 1038 var S = T.children('div.articleListTitle').children('a').text(); 1039 if(S.indexOf('Index') !== -1 || S.endsWith(' Introduction')){ 1040 T.prependTo(AC); // Move to start of article list 1041 bKeepGoing = false; 1042 console.log('Moved Index article to first position.'); 1043 } 1044 } 1045 }); 1046 } 1047 } 1048 1049 // Search only appears in R mode 1050 CPS.addClass('NarrowR'); 1051 CPS = CPS.find('div.search-overlay'); // Re-define CPS 1052 CPS.show(); 1053 CPS.find('input.text').attr("autocomplete","off"); 1054 // Link white-eye-glass to hidden search button. 1055 var HiddenSearchBoxR = CPS.find('input.button'); 1056 CPS.find('img.search-EyeGlass').click(function(){HiddenSearchBoxR.click();}); // set up the click. 1057 } 1058 1059 1060} else if (bOnSystemPage || bOnSystemPopupPage) { 1061 1062 // work out what kind of page we are on. 1063 var PageType = window.location.pathname.toLowerCase(); 1064 if (PageType.endsWith(".aspx")) { 1065 PageType = PageType.substring(0, PageType.indexOf(".aspx")); 1066 PageType = PageType.replace(/\//g, "_"); // replace all / to _ Have to use \/ to get a / in the reg-ex. The g denotes a global exchange. 1067 PageType = PageType + "_aspx"; 1068 } else if (PageType.indexOf(".html") === (PageType.length - 5)) { 1069 // Assume we are on a local machine. 1070 PageType = '_user_registration_aspx'; 1071 } 1072 //alert(PageType); 1073 1074 /* Possible page types are now: 1075 '_calendar_month_aspx' 1076 '_media_allmedia_aspx' 1077 '_user_registration_aspx' 1078 '_user_copyright_aspx' 1079 '_user_termsandconditions_aspx' 1080 '_user_privacypolicy_aspx' 1081 '_user_help_aspx' 1082 '_publisher_search_aspx' - this is search results. 1083 '_paymentgroup_registration_aspx' 1084 '_myarea_walletitem_aspx' 1085 */ 1086 1087 if (SectionTagExists("slice_system_page")) { // check if slice exists, and load into SectionTag if it does 1088 SystemSlice = SectionTag; 1089 SystemSlice.addClass(PageType); // add class onto <section> tag, so CSS can locate it. 1090 } else { 1091 BodyTag.addClass(PageType); // add class onto <body> tag, so CSS can locate it. This will apply to various pop-up windows eg shop T&Cs. 1092 BodyTag.addClass('system_popup'); // add this in case it is not on. 1093 } 1094 1095 if (PageType === '_media_allmedia_aspx' || PageType === '_publisher_search_aspx') { 1096 1097 // Add a toggle for the media controls.
1098 var MediaControls = SystemSlice.find('div#media_controls'); // these media controls are on the search page too. 1099 if (MediaControls.length !== 0) { 1100 $('<a class="system_toggle_advanced">Advanced Options</a>').insertBefore(MediaControls); 1101 ApplyToggleVisibilityOnClick(SystemSlice, "a.system_toggle_advanced", MediaControls, 0, false); 1102 } 1103 1104 HideDivsIfAllEmpty('media_summary_image'); // Hide some empty columns, if needed. 1105 1106 if (PageType === '_publisher_search_aspx') { // Extra things to do on the search page. 1107 1108 HideDivsIfAllEmpty('search_article_image'); // Hide some empty columns, if needed. 1109 HideDivsIfAllEmpty('search_event_image'); // Hide some empty columns, if needed. 1110 1111 // If we have been sent to the search page explicitly then prepare the page for searching. 1112 var SearchBox = SystemSlice.find('input[id$="_txtSearchStringTemplate"]'); 1113 if (SearchBox.length === 1) { 1114 if (SearchBox.val() === 'Activate_Search') { 1115 SystemSlice.find('h2').hide(); // hide the search result titles 1116 SearchBox.val(''); // Clear the search text box 1117 SearchBox.attr('placeholder','Type your search text here'); 1118 SearchBox.attr("autocomplete","off"); 1119 MediaControls.show(); // make the search controls show. 1120 } 1121 } 1122 1123 // If no data is found then, print a message, rather than have a blank page. 1124 if (SystemSlice.find('div.system_section').length === 0) { 1125 var HTML = '<span>No data found.<br><br>Please use the advanced options to refine your search.</span>'; 1126 $(HTML).appendTo(SystemSlice.find('div.system_body')); 1127 MediaControls.show(); // make the search controls show. 1128 } 1129 } 1130 } 1131 1132 // Fix calendar mobile page. Add a class to days we want to hide on the mobile/list view. 1133 if (PageType === '_calendar_month_aspx') { 1134 var DivToday = SystemSlice.find('div.calendar_day_wrapper_today'); 1135 if (DivToday.length !== 0) { // we are on a calendar page with today's date. 1136 var NoEvents = SystemSlice.find('div#calendar_no_events'); 1137 if (NoEvents.length === 0) { // only bother if there are some events. 1138 DivToday.prevAll().addClass('CalendarHideOnListView'); // so we can hide days earlier in the current week. 1139 var DivThisWeek = DivToday.parent(); 1140 DivThisWeek.prevAll().addClass('CalendarHideOnListView'); // so we can hide earlier weeks. 1141 // If no events are visible, then tell the user. 1142 var AllDaysInVisibleWeeks = SystemSlice.find('div.calendar_week:not(".CalendarHideOnListView") div.calendar_day_wrapper'); 1143 var iDaysVisible = AllDaysInVisibleWeeks.not('.calendar_day_wrapper_empty').not('.CalendarHideOnListView').length; 1144 if (iDaysVisible === 0) { 1145 $('<div id="calendar_no_events">There are no events in the selected month.</div>').insertAfter(SystemSlice.find('div.calendar')); 1146 } 1147 } 1148 } 1149 } 1150 1151} // end of bOnHomePage or bOnSystemPage if-block 1152 1153// Corrections for various hardware/browsers 1154var P = navigator.platform; 1155var bSmallAppleDevice = (P === 'iPhone' || P === 'iPad' || P === 'iPod'); 1156//var bAppleDevice = (P === 'MacIntel' || bSmallAppleDevice); 1157 1158var UA = navigator.userAgent; 1159// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent for details. 1160var bOnSafari = (UA.indexOf('Safari/') !== -1 && UA.indexOf('Chrome/') === -1 && UA.indexOf('Chromium/') === -1); 1161 1162//alert(P + ' # ' + UA); // DEBUGGING line. 1163 1164if (bOnSafari) { 1165 // Fix the twitter feed on Safari. Need to replace height:100% with a fixed height, to prevent a near infinite scroll. 1166 // We can't just add a class on the <iframe>, as it is created dynamically by Twitter js. 1167 // So instead we add a class on the wrapper div, just before where the iframe will appear. 1168 // SectionTags.find('div.WhatsOnTwitter').addClass('OnAppleDevice'); 1169} 1170if (bSmallAppleDevice) { 1171 // Parallex images are often a mess on small apple devices, so add a tag onto the <body> tag so we can take evasive action. 1172 BodyTag.addClass('OnSmallAppleDevice'); 1173} 1174 1175// Sort out login/logout/register/web-office links 1176if (bUserLoggedIn) { 1177 var SB = BodyTag.find('div.HiddenStatusBar'); 1178 if (SB.length === 1) { 1179 var bWebOfficeActive = (SB.find('a.weboffice_link').length === 1); 1180 if (!bWebOfficeActive) { // Need to hide WO links. 1181 BodyTag.find('section.NewsLetterFooter a.FooterWebOffice').hide(); 1182 } 1183 } 1184} 1185 1186// Fix the cookies slice 1187var CS = BodyTag.find('footer div.slice_Cookies'); 1188 if (CS.length === 1) { 1189 CS.find('img').attr('src','/Images/Content/2019/Templates/54496/images/IconClose.png'); 1190 } 1191
1192// Linked In images 1193 /* 1194var HeadTag = $('head'); 1195var MetaTag = HeadTag.find('meta[name="image"]'); 1196 if(MetaTag.length === 1){ 1197 MetaTag.attr('property','og:image'); 1198 } 1199 */ 1200 1201// Sticky header 1202// We need iYforHeaderTintDown - iYforHeaderTintUp to be larger than the difference between heights 1203// for the large and small headers. 1204var HeaderSlice = BodyTag.find('header'); 1205var SlickNavBtn = HeaderSlice.find("a.slicknav_btn"); 1206 1207var bHeaderTintOn = false, iYforHeaderTintDown = 50, iYforHeaderTintUp = 2; 1208function PollScrollDownChanges() { // This routine must be very streamlined. Called every 250ms. 1209 1210 var iY = window.pageYOffset; 1211 1212 if (!bHeaderTintOn && iY >= iYforHeaderTintDown) { 1213 if (window.innerWidth > 991) { // only apply if screen is of desktop size. 1214 HeaderSlice.addClass('HeaderSmall'); 1215 bHeaderTintOn = true; 1216 } 1217 } 1218 if (bHeaderTintOn && iY < iYforHeaderTintUp) { 1219 HeaderSlice.removeClass('HeaderSmall'); 1220 bHeaderTintOn = false; 1221 } 1222} 1223 1224// If the screen is resized, then we have to click shut the SlickNav Menu, if it is open. 1225var iLastWidth = 0; 1226function ShutSlickNav() { 1227 var iWidth = window.innerWidth; 1228 if (iWidth !== iLastWidth) { // don't run code if it looks like we just have the browser top menu appearing and disappearing. 1229 iLastWidth = iWidth; 1230 if (bDesktopScreenPossible) { 1231 if (SlickNavBtn.hasClass('slicknav_open')){ 1232 SlickNavBtn.click(); 1233 } 1234 if (bOnHomePage && iWidth < 992 && HeaderSlice.hasClass('HeaderSmall')) { 1235 HeaderSlice.removeClass('HeaderSmall'); 1236 bHeaderTintOn = false; 1237 } 1238 } 1239 } 1240} 1241 1242window.addEventListener("resize", function(){ShutSlickNav();}, false); 1243if (bDesktopScreenPossible) { 1244 window.setInterval(function(){PollScrollDownChanges();}, 100); // poll to see if user has scrolled down. 1245} 1246 1247}); 1248 1249// Dummy routines to prevent errors 1250function insertFolderImages() {return false;}
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.