1/* 2 Main ChurchInsight template Javascript/JQuery file. Version 20.Feb.2017 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 14// Custom values set here. Change for a particular customer. 15var SlideShowDefaultButtonText = 'Read more'; 16var bAddDarkenedOverlayForSlideShowCaptions = false; 17var bSplitFooterAddressAtSecondComma = true; 18 19// #################### Define some useful functions ####################### 20 21// We have to put all functions here, as OSX does not allow functions to be inside if statements. 22 23// function to turn a slice name into a selector reference for the corresponding <section> tag 24function GetSectionTagRef(SliceName) { 25 return 'section.' + SliceName + ' '; 26} 27 28var SectionTag, SectionTags; // will be used to hold required slices 29function SectionTagExists(SliceName) { 30 if (SectionTags.hasClass(SliceName)) { 31 SectionTag = SectionTags.filter(GetSectionTagRef(SliceName)); 32 if (SectionTag.length !== 0) { // at least one slice exists, great. You could have more than one in theory. 33 return true; 34 } 35 } 36 SectionTag = undefined; // remove all data. 37 return false; 38} 39 40function GetRefItem(SectionTag, Ref) { 41 if (typeof Ref === "string") { 42 return SectionTag.find(Ref); 43 } else { 44 return Ref; 45 } 46} 47 48// A function to easily set JQuery toggles. 49// SectionTag is a $ variable. 50function ApplyToggleOnClick(SectionTag, ClickRef, ToggleRef, iDelay, bShowToggleItemInitially) { 51 52 var ClickItem = GetRefItem(SectionTag, ClickRef); 53 var ToggleItem = GetRefItem(SectionTag, ToggleRef); 54 55 if (bShowToggleItemInitially) { 56 ToggleItem.show(0); 57 } else { 58 ToggleItem.hide(0); 59 } 60 // Note we add a function here. Since we are only using calling function arguements inside the function argument, 61 // variable scoping correctly works. 62 ClickItem.click(function () { 63 ToggleItem.toggle(iDelay); 64 }); 65} 66 67/* 68function ApplyHideOnClick(SectionTag, ClickRef, ToHideRef) { 69 70 var ClickItem = GetRefItem(SectionTag, ClickRef); 71 var ToHideItem = GetRefItem(SectionTag, ToHideRef); 72 73 ClickItem.click(function () { 74 ToHideItem.hide(0); 75 }); 76} 77*/ 78 79function ApplyToggleClassOnClick(SectionTag, ClickRef, ToggleRef, ClassName) { 80 81 var ClickItem = GetRefItem(SectionTag, ClickRef); 82 var ToggleItem = GetRefItem(SectionTag, ToggleRef); 83 84 // Note we add a function here. Since we are only using calling function arguements inside the function argument, 85 // variable scoping correctly works. 86 ClickItem.click(function () { 87 ToggleItem.toggleClass(ClassName); 88 }); 89} 90 91function ApplyToggleVisibilityOnClick(SectionTag, ClickRef, ToggleRef, iDelay, bShowToggleItemInitially) { 92 93 var ClickItem = GetRefItem(SectionTag, ClickRef); 94 var ToggleItem = GetRefItem(SectionTag, ToggleRef); 95 96 if (bShowToggleItemInitially) { 97 ToggleItem.show(0); 98 } else { 99 ToggleItem.hide(0); 100 } 101 // Note we add a function here. Since we are only using calling function arguements inside the function argument, 102 // variable scoping correctly works. 103 ClickItem.click(function () { 104 ToggleItem.toggle(iDelay); 105 }); 106} 107 108// function to test if text exists. 109var sAttrText, sAttrText2, sAttrText3, sAttrText4; // Results come back in these variables. 110var DollarTextarea = $("<textarea/>"); // store this once. 111function TextExists(attrText, bSplit) { 112 113 if (attrText === undefined) {return false;} 114 if (attrText === null) {return false;} 115 116 var TextToProcess = attrText.trim(); 117 if (TextToProcess === '') {return false;} 118 119 // decode the text, so that &lt; becomes < etc. 120 // This works by turning into HTML and then turning back into text. 121 if (TextToProcess.indexOf('&') !== -1) { // we could use the .includes('&') method, but it is quite new, so some browsers can't cope. 122 TextToProcess = DollarTextarea.html(TextToProcess).text(); 123 } 124 if (TextToProcess === '') {return false;} 125 126 sAttrText = ''; // set return values to blank. 127 sAttrText2 = ''; 128 sAttrText3 = ''; 129 sAttrText4 = ''; 130 if (bSplit) { 131 var arrSplitText = TextToProcess.split('*'); 132 sAttrText = arrSplitText[0].trim(); 133 if (arrSplitText.length > 1) {sAttrText2 = arrSplitText[1].trim();} 134 if (arrSplitText.length > 2) {sAttrText3 = arrSplitText[2].trim();} 135 if (arrSplitText.length > 3) {sAttrText4 = arrSplitText[3].trim();} 136 } else { 137 sAttrText = TextToProcess; 138 } 139 140 return (sAttrText + sAttrText2 + sAttrText3 + sAttrText4 !== ''); 141} 142
143// Function to hide a column if it contains no images. 144var SystemSlice; 145function HideDivsIfAllEmpty(ColumnClass) { 146 var ImageWrappers = SystemSlice.find('div.' + ColumnClass); 147 if (ImageWrappers.find('img').length === 0) { // have to use find not children, as img tags can be inside <a> tags. 148 ImageWrappers.hide(0); 149 } 150} 151 152// ################### Slice activation functions go here. ######################### 153 154// All slide shows have the same defaults at present. 155var BxDefaultValues; 156function ActivateBxSlider(SliceName) { 157 if (SectionTagExists(SliceName)) { // check if slice exists, and load into SectionTag if it does 158 159 var bannerSlides = SectionTag.find('div.bannerSlides'); // use a "find" here, as structure of slices varies. 160 var gallery_ul = bannerSlides.children('ul.gallery_ul'); 161 var ImageList = gallery_ul.find('img'); 162 if (ImageList.length === 0) {return;} // No images, so give up. 163 164 // ul.gallery_ul must be displayed before bx-slider can be applied. 165 // So since we hide it while the page was loading, we show it now. 166 bannerSlides.show(0); // show the slice now. It was hidden by CSS. 167 168 if (ImageList.length > 1) { // carry on as normal. 169 gallery_ul.bxSlider(BxDefaultValues); 170 } else { // Just 1 image, so we don't set up the slider, but do some minor adjustments to help the CSS. 171 gallery_ul.css('margin','0px').css('list-style-type','none'); 172 var S = '<div class="bx-wrapper"><div class="bx-viewport"></div></div>'; 173 gallery_ul.wrap(S); 174 } 175 176 // Code to enable user defined text to appear over banner slides. 177 ImageList.each(function() { 178 var ThisImg = $(this); 179 if (TextExists(ThisImg.attr('alt'), true)) { // check if there is any alt text. 180 var DarkenedClass = ''; 181 if (bAddDarkenedOverlayForSlideShowCaptions) {DarkenedClass = ' DarkenedOverlay';} 182 var title = '<div class="slideTitle' + DarkenedClass + '">' + sAttrText + '</div>'; 183 // even if the subtitle text is empty, we keep the div for styling reasons. 184 // If there is a long caption, reduce font weight from bold to normal. 185 var FontStyle = ''; 186 if (sAttrText2.length > 100) {FontStyle = ' style="font-weight:400;" ';} 187 var subtitle = '<div class="slideText' + DarkenedClass + '"' + FontStyle + '>' + sAttrText2 + '</div>'; 188 189 var ButtonLink = ''; 190 var ButtonText = sAttrText3; 191 if (ButtonText === '') {ButtonText = SlideShowDefaultButtonText;} 192 var TextColor = ''; 193 if (ButtonText !== '' && ButtonText !== 'none'){ 194 var ButtonColor = sAttrText4; 195 TextColor = 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 //sAttrText = 'javascript:location.href="' + sAttrText + '";'; 206 ButtonLink = '<a class="slideButton" href="' + sAttrText + '"' + ButtonColor + '>' + ButtonText + '</a>'; 207 } 208 } 209 if(TextColor !== '') { 210 title = title.replace('<div','<div style="color:' + TextColor + ';"'); 211 subtitle = subtitle.replace('<div','<div style="color:' + TextColor + ';"'); 212 } 213 var caption = '<div class="caption">' + title + subtitle + ButtonLink + '</div>'; 214 $(caption).insertAfter(this); 215 } 216 }); 217 218 // Re-factor the HTML on touch devices, so that swiping will work. 219 if(bOnTouchDevice && ImageList.length > 1){ 220 gallery_ul.children().children('a').each(function() { // > li > a 221 var ThisA = $(this); 222 if(ThisA.find('a').length === 1){ 223 ThisA.children().insertAfter(ThisA); 224 ThisA.hide(); 225 } 226 }); 227 } 228 229 } 230} 231 232// define a function, so we can activate a SlickNav menu in a controlled way. 233var SlickNavBtn, HeaderSlice; 234var IEDy = 0, bEDopen = false; 235function ActivateMenu(SliceName) { 236 if (SectionTagExists(SliceName)) { // check if slice exists, and load into SectionTag if it does 237 238 var SectionTagRef = GetSectionTagRef(SliceName); 239 var RootMenuDeskTop = SectionTag.children('div.nav-menu').children('ul.root_menu'); 240 241 RootMenuDeskTop.slicknav({ // activate SlickNav for this slice. 242 prependTo: SectionTagRef + '> div.SlickNav_Wrapper', 243 allowParentLinks: true, // Top level items can be links 244 label: 'Menu', 245 // Use hex escape characters here. 246 closedSymbol: '', // a logical OR "V" symbol 247 openedSymbol: '', // a nice up pointing ">" symbol 248 duplicate: bDesktopScreenPossible // only need to duplicate if the desktop menus might be needed. 249 }); 250 251 // Add extra links onto the menu, to replace top-link log-out buttons etc. 252 // We can only do this after the menu is initialised, so that class "slicknav_nav" exists. 253 var ExtraLink_0 = ''; 254 var ExtraLink_1, ExtraLink_2; 255 if (bUserLoggedIn) { 256 ExtraLink_0 = '<li class="ExtraLink"><a href="/MyArea/Introduction.aspx"><i class="icomoon-TopLinks-MyArea"></i>My Area</a></li>'; 257 ExtraLink_1 = '<li class="ExtraLink"><a href="/User/Logout.aspx"><i class="journey-icon-login"></i>Logout</a></li>'; 258 ExtraLink_2 = '<li class="ExtraLink"><a href="/Admin/Default.aspx"><i class="icomoon-TopLinks-WebOffice"></i>Web Office</a></li>'; 259 } else { 260 ExtraLink_1 = '<li class="ExtraLink"><a href="/user/login.aspx"><i class="journey-icon-login"></i>Login</a></li>'; 261 ExtraLink_2 = '<li class="ExtraLink"><a href="/User/Registration.aspx"><i class="icomoon-TopLinks-Register"></i>Register</a></li>'; 262 } 263 var ExtraLink_3 = '<li class="ExtraLink SearchOpen"><a><i class="journey-icon-search"></i>Search</a></li>'; 264 var SlickNavLastItem = SectionTagRef + 'ul.slicknav_nav > li:last-child'; 265 $(ExtraLink_0 + ExtraLink_1 + ExtraLink_2 + ExtraLink_3).insertAfter(SlickNavLastItem); 266 267 if (bOnTouchDevice && bDesktopScreenPossible) { // have to do more work on menus. 268 269 // Having made the SlickNav menu - delete what we don't want. 270 271 SectionTag.children("div.SlickNav_Wrapper").children("div.slicknav_menu").children('ul.slicknav_nav').find('li.SlickNavNotNeeded').remove(); 272 273 // deactivate the top level <a> tag in the desk-top version so touch-screens work correctly. 274 // The link goes nowhere, but retains all the styling. 275 RootMenuDeskTop.children("li.has_sub_menu").children('a').removeAttr("href"); 276 } 277 278 // Add a close menu icon into slickNav. 279 var SlickNavIcon = SectionTag.find('span.slicknav_icon'); 280 $('<div class="SlickNavCloseIcon"></div>').insertAfter(SlickNavIcon); 281 282 // apply all the visibility on-clicks to make the menu slice work. 283 284 // Find some commonly used items. 285 var SearchOverlay = SectionTag.parent().children("div.search-overlay"); 286 var MobileSearchOpen = SectionTag.find("div.SlickNav_Wrapper li.ExtraLink.SearchOpen"); 287 SlickNavBtn = SectionTag.find("a.slicknav_btn"); 288 //var Logo = SectionTag.find("div.logo-container"); 289 290 //ApplyToggleOnClick(SectionTag, "li.ExtraLink.SearchOpen", SearchOverlay, 0, false); 291 // Open search function. 292 MobileSearchOpen.click(function(){ 293 SearchOverlay.addClass('On'); 294 SearchOverlay.find('input.text').focus(); 295 }); 296 297 //ApplyToggleOnClick(SectionTag, "div.top-link-wrapper a:nth-child(3)", SearchOverlay, 0, false); 298 //ApplyToggleVisibilityOnClick(SectionTag, "div.top-link-wrapper a:last-child", SearchOverlay, 0, false); 299 300 //ApplyHideOnClick(SectionTag, "a.search-close", SearchOverlay); 301 //ApplyHideOnClick(undefined, SlickNavBtn, SearchOverlay); 302 // Toggles for menu-bars and menu-close icons 303 ApplyToggleOnClick(undefined, SlickNavBtn, SlickNavIcon, 0, true); // no delay on the toggle.
304 ApplyToggleOnClick(SectionTag, SlickNavBtn, "div.SlickNavCloseIcon", 0, false); // no delay on the toggle. 305 306 // Make fixed slicknav scrollable. 307 var Mask = SectionTag.parent().children('div.MobileMenuMask'); 308 ApplyToggleVisibilityOnClick(undefined, SlickNavBtn, Mask, 0, false); // no delay on the toggle. 309 ApplyToggleClassOnClick(SectionTag, SlickNavBtn, SectionTag, 'SlickNavFullWidth'); 310 SlickNavBtn.click(function(){ 311 if(!bEDopen){ 312 IEDy = window.pageYOffset; 313 window.scrollTo(0,0); 314 } else { 315 window.scrollTo(0,IEDy); 316 } 317 bEDopen = !bEDopen; 318 }); 319 320 var LastMenuLi = SectionTag.find("ul.root_menu > li:last-child a"); 321 LastMenuLi.click(function(){ 322 SearchOverlay.addClass('On'); 323 SearchOverlay.find('input.text').focus(); 324 //Mask.show(); 325 }); 326 var SearchClose = SectionTag.parent().find('a.search-close'); 327 SearchClose.click(function(){ 328 SearchOverlay.removeClass('On'); 329 //if(!SlickNavBtn.hasClass('slicknav_open')){ 330 //Mask.hide(); 331 //} 332 }); 333 334 // Need autocomplete="off" to be added to the search box <input> tag. 335 // This stops horrible browser autocomplete text from appearing. 336 SectionTag.find('div.search_div input').attr("autocomplete","off"); 337 338 } 339} 340 341function ActivateFooter(SliceName) { 342 if (bSplitFooterAddressAtSecondComma) { 343 if (SectionTagExists(SliceName)) { // check if slice exists, and load into SectionTag if it does 344 // .footer-column-2 can be a div or a span, so just look for the class. 345 var FooterAddress = SectionTag.find('.footer-column-2'); 346 var AddressText = FooterAddress.text(); 347 AddressText = AddressText.replace(/\,/, "¬"); // change first comma 348 AddressText = AddressText.replace(/\,/, ",<br>"); // now break at the 2nd comma 349 AddressText = AddressText.replace(/¬/, ","); // put back first comma 350 FooterAddress.html(AddressText); 351 } 352 } 353} 354 355// The css needed for the code below is already in ContentPage.css files 356var LIs; 357function RemoveActiveLink(GNum) { 358 var Link = '/Groups/' + GNum + '/'; 359 var A = LIs.children('a[href^="' + Link + '"]'); 360 A.removeAttr('href').css('cursor','auto'); 361 if (bOnTouchDevice){A.next().children().eq(0).remove();} 362 // Check top box of side-bar group-nav 363 var BHM = BodyTag.find('nav td.boxout_header_middle a'); 364 if(BHM.length === 1 && !BHM.hasClass('NotActiveGroupNavBoxLink') && BHM.attr('href').startsWith(Link)){ 365 BHM.removeAttr('href').addClass('NotActiveGroupNavBoxLink'); 366 } 367 if (location.pathname.startsWith(Link)){ 368 if (SectionTagExists('slice_content_page')) { 369 if(SectionTag.find('div.main-content').length === 0){ 370 var H = '<div class="main-content"><div class="ArticleBody"></div></div>'; 371 $(H).prependTo(SectionTag.find('div.container')); 372 } 373 var SideLinks = SectionTag.find('aside nav div.group_nav_selected').clone(); 374 SideLinks.addClass('ClonedGroupNav'); 375 var Atag = SideLinks.children('a'); 376 Atag.removeAttr('href'); 377 $('<div>Please choose a sub-page:</div>').insertAfter(Atag); 378 SectionTag.find('div.main-content div.ArticleBody').html(SideLinks); 379 } 380 } 381} 382 383var iMissingImage = 0; 384function AddMissingImageHTML(Card, prefix){ 385 if(Card.find('img').length === 0){ 386 iMissingImage++; 387 if(iMissingImage === 7){iMissingImage = 1;} 388 var href = Card.find('div.' + prefix + 'ListTitle a').attr('href'); 389 var ImgSrc = '/Hubb/Images/Background-0' + iMissingImage.toString() + '.jpg'; 390 var S = '<div class="' + prefix + 'ListImage"><a href="' + href + '"><img src="' + ImgSrc + '"></a></div>'; 391 $(S).prependTo(Card); 392 } 393} 394 395function ActivateArticleList3(SliceName) { 396 if (SectionTagExists(SliceName)) { // check if slice exists, and load into SectionTag if it does 397 398 // Get the parallax image 399 var ImgSrc = SectionTag.children('div.HideElement').find('img'); 400 if(ImgSrc.length > 0){ 401 var S = 'url(' + ImgSrc.eq(0).attr('src') + ')'; 402 SectionTag.css('background-image',S); 403 } 404 405 SectionTag.find('div.UML_AL_1 > div').each(function () { 406 var ThisCard = $(this); 407 AddMissingImageHTML(ThisCard,'article'); 408 }); 409 410 // Get the summaries 411 var Summarys = SectionTag.find('div.articleListSummary span'); 412 413 // Create the links at the bottom of the article cards. 414 var j=0; 415 SectionTag.find('div.articleListTitle a').each(function () { 416 var ThisAtag = $(this); 417 var titleLink = ThisAtag.attr("href"); 418 var articleListLink = ThisAtag.parent().parent().children('.articleListLink'); 419 // See if we have new link text. 420 if (TextExists(Summarys.eq(j).text(), true)) { 421 if (sAttrText2 !== '') { 422 articleListLink.text(sAttrText2); 423 } 424 } 425 articleListLink.wrapInner('<a class="ArrowToRight" href="' + titleLink + '">'); 426 j++; 427 }); 428 429 Summarys.each(function () { 430 var ThisSummary = $(this); 431 var S = ThisSummary.text(); 432 if (TextExists(S, true)) { 433 sAttrText = sAttrText.replace(/\\/g,'<br>'); 434 if (S !== sAttrText) { 435 ThisSummary.html(sAttrText); 436 } 437 } 438 });
439 } 440} 441 442function ActivateEventsList4(SliceName) { 443 if (SectionTagExists(SliceName)) { // check if slice exists, and load into SectionTag if it does 444 SectionTag.find('div.UML_EL_1 > div').each(function () { 445 var ThisCard = $(this); 446 AddMissingImageHTML(ThisCard,'event'); 447 var ThisDate = ThisCard.find('div.eventListDate'); 448 var S = ThisDate.text(); 449 // If date looks like a US version ie. "MMM DD", then swap some stuff around. 450 var S13 = S.substr(0,1); 451 if(S13 === 'J' || S13 === 'F' || S13 === 'M' || S13 === 'A' || S13 === 'S' || S13 === 'O' || S13 === 'N' || S13 === 'D'){ 452 S = S.substr(3,3).trim() + ' ' + S.substr(0,3) + ' ' + S.substr(6).trim(); 453 } 454 // Now carry on, as all dates are in 'DD MMM' format. 455 ThisDate.text(S.substr(6).trim()); 456 var DN = S.substr(0,2).trim(); 457 if(DN.length === 1){DN = '0' + DN;} 458 var DM = S.substr(2,4).trim().toUpperCase(); 459 var BoxDate = '<div class="BoxDate"><div>' + DN + '</div><div>' + DM + '</div></div>'; 460 $(BoxDate).appendTo(ThisDate); 461 }); 462 } 463} 464 465function ActivateMediaList4(SliceName) { 466 if (SectionTagExists(SliceName)) { // check if slice exists, and load into SectionTag if it does 467 SectionTag.find('div.UML_ML_1 span.MediaList > div').each(function () { 468 var ThisCard = $(this); 469 AddMissingImageHTML(ThisCard,'media'); 470 var BoxDate = '<div class="BoxDate"><span></span></div>'; // Icon added to the <span> via CSS 471 var ImageLink = ThisCard.find('div.mediaListImage a'); 472 $(BoxDate).appendTo(ImageLink); 473 }); 474 } 475} 476 477function ActivateBlockImages(SliceName) { 478 if (SectionTagExists(SliceName)) { // check if slice exists, and load into SectionTag if it does 479 SectionTag.find("div.image_blocks img" ).each(function() { 480 var ThisImg = $(this); 481 if (TextExists(ThisImg.attr('alt'), true)) { // check if there is any alt text. 482 var cardGridCaption = '<div class="image_block_title_wrapper"><div class="image_block_title">' + sAttrText + '</div><div class="image_block_text">' + sAttrText2 + '</div></div>'; 483 $(cardGridCaption).insertAfter( ThisImg ); 484 } 485 ThisImg.removeAttr('title'); // remove the title attribute so that pop-up text does not appear. 486 }); 487 } 488} 489 490function ActivateSlideShowSideBar(SliceName) { 491 //return; 492 if (SectionTagExists(SliceName)) { // check if slice exists, and load into SectionTag if it does 493 var AB = SectionTag.find("div.SlideShowArticle div.ArticleBody"); 494 var S = '<div class="DropBelow"></div>'; 495 $(S).insertAfter(AB.children().eq(3)); 496 var Tags = AB.children(); 497 var DB = Tags.eq(4); 498 Tags.eq(2).clone().prependTo(DB); 499 Tags.eq(1).clone().prependTo(DB); 500 Tags.eq(0).clone().prependTo(DB); 501 } 502} 503 504// ########################## Check various conditions ############################# 505 506var bOnTouchDevice = ('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0); 507var iDeskTopWidth = 992; 508var iMobileScreenAllowence = 64; // Because of other stuff on a screen, you have to assume the browser window could get bigger on a rotation. 509var bDesktopScreenPossible = ((screen.width + iMobileScreenAllowence) >= iDeskTopWidth || (screen.height + iMobileScreenAllowence) >= iDeskTopWidth); 510 511var BodyTag = $('body'); 512var bOnSystemPopupPage = BodyTag.hasClass('system_popup') || (window.location.href.toLowerCase().indexOf('popup=yes') !== -1); 513var bUserLoggedIn = BodyTag.hasClass('logged_in_user'); 514 515SectionTags = BodyTag.find('section'); // Store all the section tags to speed up later code. 516var bOnContentPage = SectionTags.hasClass('slice_content_page'); 517var bOnSystemPage = SectionTags.hasClass('slice_system_page'); 518var bOnHomePage = SectionTags.hasClass('slice_SlidesFullWidth'); 519 520// Corrections for various hardware. 521var P = navigator.platform.trim().toLowerCase(); 522//alert('Device: ' + P); 523var bSmallAppleDevice = (P === 'iphone' || P === 'ipad' || P === 'ipod'); 524if (bSmallAppleDevice) { 525 BodyTag.addClass('OnSmallAppleDevice'); 526 //alert('DeviceX: ' + P); 527} 528 529// Activate the slide shows first as they are usually near the top of the visible screen. 530if (bOnHomePage) { 531 532 // ############################################################## 533 // # js for Slide Shows slices. We use BX-slider V4.2.5 534 // ############################################################## 535 536 // The slide-shows are hidden via CSS when the page first loads, to give a smoother page-load experience. 537 // All slide-show CI modules must have a class "bannerSlides" defined within them. 538 539 // Activate all the slide-shows. Do in sensible order, so any visible ones are done first. 540// All slide shows have the same defaults at present. 541 BxDefaultValues = { 542 mode: 'fade', 543 auto: true, 544 pause: 8000, 545 speed: 500, 546 pager: true, 547 controls: false, 548 preloadImages: 'all', 549 adaptiveHeight:true, 550 touchEnabled:false, 551 buildPager: function(i){return i+1;} 552 }; 553 ActivateBxSlider('slice_SlidesFullWidth'); 554} 555 556// ####################################### 557// # Menu data changes 558// ####################################### 559 560// We make the required adjustments to the one set of menu HTML on the page, before cloning it and activating all the copies. 561 562var ulModuleRootMenu = BodyTag.find('ul.root_menu'); 563var bMenuPresent = (ulModuleRootMenu.length !== 0); 564if (bMenuPresent) { 565 566 /* remove sub menus from Home */ 567 // We check that the first link actually looks like a "Home" one. 568 // We assume that the home menu (if present) is the first item within a menu. 569 var HomeMenuLi = ulModuleRootMenu.children('li:first-child'); 570 if(HomeMenuLi.children('a').text().trim().toLowerCase() === 'home'){ 571 HomeMenuLi.children('ul').remove(); 572 HomeMenuLi.removeClass('has_sub_menu'); // remove class 573 } 574 575 // Make sure the online bible goes to a fresh tab/page. 576 ulModuleRootMenu.find('a[href$="/Online_Bible.aspx"]').attr("target","_blank"); 577 578 // Set up the search icon in the search box. 579 /* 580 var DeskTopSearchBox = BodyTag.find('header div.top-link-wrapper div.search-form'); 581 $('<i class="journey-icon-search"></i>
581').appendTo(DeskTopSearchBox); 582 var HiddenSearchBox = DeskTopSearchBox.find('input.button'); 583 var EyeGlass = DeskTopSearchBox.find('i'); 584 EyeGlass.click(function(){HiddenSearchBox.click();}); // set up the click. 585 var InputText = DeskTopSearchBox.find('input.text'); 586 InputText.focus(function(){EyeGlass.addClass('InFocus');}); 587 InputText.blur(function(){EyeGlass.removeClass('InFocus');}); 588 */ 589 590 if (bUserLoggedIn) { 591 //ulModuleRootMenu.children('li:last-child').children('ul').remove(); // delete submenus of Myarea. 592 BodyTag.find('header div.top-link-wrapper a.Login').attr('href','/user/logout.aspx').text('LOGOUT'); 593 BodyTag.find('header div.top-link-wrapper a.Bookings').attr('href','/admin').text('WEB OFFICE'); 594 } 595 596 // remove copies of 1st item elements in dropdown sub-menu. 597 ulModuleRootMenu.find('li.menu_item_level_2:first-child').each(function() { 598 599 var ThisLi = $(this); 600 if(ThisLi.children("a[href^='/MyArea/']").length === 0) { // only if not a link into /MyArea/... 601 602 if(ThisLi.siblings().length === 0) { // no other <li> so it is the only entry 603 var ul = ThisLi.parent(); 604 ul.parent().removeClass('has_sub_menu'); // remove class from the <li> at the level above 605 ul.remove(); // delete whole parent <ul> 606 607 } else { 608 if (bOnTouchDevice && bDesktopScreenPossible) { 609 // On a touch device, the copies of the level one links at the 2nd level have to be kept for the desktop menus. 610 // But in the SlickNav menus, these 2nd level links are not needed. 611 // So we mark the items so we can delete them later, after data is copied into the SlickNav menu. 612 ThisLi.addClass('SlickNavNotNeeded'); // Mark the 2nd level <li> tag. 613 } else { 614 // Not on a touch screen, so Desktop and SlickNav menus will be the structurally the same. 615 ThisLi.remove(); // so just remove this <li> tag 616 } 617 } 618 } 619 }); 620 621/* 622LIs = ulModuleRootMenu.children(); 623RemoveActiveLink ('351004'); 624RemoveActiveLink ('351006'); 625*/ 626 627 $('<li class="MenuSearchOpen"><a><i class="journey-icon-search"></i></a></li>').appendTo(ulModuleRootMenu); 628 629 // ####################################### 630 // # SlickNav menus V1.0.10 631 // ####################################### 632 633 ActivateMenu('slice_Header_L'); 634 635 // ######## Footer Slice code #################### 636 637 // If there is a header, then there is probably a footer. 638 // This is the footer top. There is no need to clone this HTML. 639 640 ActivateFooter("slice_FooterTop_L"); 641 642} // end of if bNeedMenus 643 644// Here do things ONLY needed on a home page. 645if (bOnHomePage) { 646 647 ActivateSlideShowSideBar('SlideShowWrapper'); 648 ActivateBlockImages('slice_Gallery4'); 649 ActivateEventsList4('EventsCardsFour'); 650 ActivateMediaList4('SermonCardsFour'); 651 652} else if (bOnContentPage) { 653 654 if (SectionTagExists('slice_content_page')) { // check if slice exists, and load into SectionTag if it does 655 656 // code to try and make content images work on mobile phones. Set max-width css property is if has not already been set. 657 // If width and height attributes are both set, then the image is compressed horizontally, but that is still better than it overflowing. 658 var AB = SectionTag.find('div.main-content'); 659 var ContentImages = AB.find('img'); 660 ContentImages.each(function() { 661 var Img = $(this); 662 if (Img.css('max-width') === 'none') { 663 Img.css('max-width','100%'); 664 } 665 }); 666 667 var TopAL = AB.find('div.TopMenuEntryAL'); 668 if(TopAL.length > 0){ 669 SectionTag.addClass('NoGroupNav'); 670 } 671 672 var FC = SectionTag.find('div.main-content div[id$="_elFormContents"]'); 673 if(FC.length > 0){ 674 SectionTag.addClass('HasForm'); 675 // Look for a invisible-recaptcha 676 var IR = FC.children('div.invisible-recaptcha'); 677 if (IR.length === 1){ 678 var ISB = FC.find('input.sitebutton[type="button"]'); 679 if (ISB.length === 1){ 680 IR.insertAfter(ISB); 681 } 682 } 683 } 684 } 685 686} else if (bOnSystemPage || bOnSystemPopupPage) { 687 688 // work out what kind of page we are on. 689 var PageType = window.location.pathname.toLowerCase(); 690 if (PageType.endsWith(".aspx")) { 691 PageType = PageType.substring(0, PageType.indexOf(".aspx")); 692 PageType = PageType.replace(/\//g, "_"); // replace all / to _ Have to use \/ to get a / in the reg-ex. The g denotes a global exchange. 693 PageType = PageType + "_aspx"; 694 } else { 695 // Assume we are on a local machine. 696 PageType = '_user_registration_aspx'; 697 } 698 //alert(PageType); 699 700 /* Possible page types are now: 701 '_calendar_month_aspx' 702 '_media_allmedia_aspx' 703 '_user_registration_aspx' 704 '_user_copyright_aspx' 705 '_user_termsandconditions_aspx' 706 '_user_privacypolicy_aspx' 707 '_user_help_aspx' 708 '_publisher_search_aspx' - this is search results. 709 '_paymentgroup_registration_aspx' 710 '_myarea_walletitem_aspx' 711 */ 712 713 if (SectionTagExists("slice_system_page")) { // check if slice exists, and load into SectionTag if it does 714 SystemSlice = SectionTag; 715 SystemSlice.addClass(PageType); // add class onto <section> tag, so CSS can locate it. 716 } else { 717 BodyTag.addClass(PageType); // add class onto <body> tag, so CSS can locate it. 718 BodyTag.addClass('system_popup'); // add this in case it is not on. 719 } 720 721 if (PageType === '_media_allmedia_aspx' || PageType === '_publisher_search_aspx') { 722 723 // Add a toggle for the media controls.
724 var MediaControls = SystemSlice.find('div#media_controls'); // these media controls are on the search page too. 725 if (MediaControls.length !== 0) { 726 $('<a class="system_toggle_advanced">Search Options</a>').insertBefore(MediaControls); 727 ApplyToggleOnClick(SystemSlice, "a.system_toggle_advanced", MediaControls, 0, false); 728 $('<div class="LineB"></div>').insertAfter(MediaControls.children().eq(3)); // do 3 before 1 729 $('<div class="LineB"></div>').insertAfter(MediaControls.children().eq(1)); 730 $('<div class="Line"></div>').appendTo(MediaControls); 731 var MediaSort = SystemSlice.find('div#media_sort'); 732 MediaSort.appendTo(MediaControls); 733 var XML = SystemSlice.find('ul#media_buttons'); 734 XML.children().children().text('( XML feed )'); 735 XML.appendTo(MediaControls); 736 var CloseImg = $('<img src="/Images/Content/2427/Templates/53446/images/IconClose.png">'); 737 CloseImg.click(function(){ 738 MediaControls.hide(); 739 }); 740 CloseImg.prependTo(MediaControls); 741 } 742 743 HideDivsIfAllEmpty('media_summary_image'); // Hide some empty columns, if needed. 744 745 if (PageType === '_publisher_search_aspx') { // Extra things to do on the search page. 746 747 HideDivsIfAllEmpty('search_article_image'); // Hide some empty columns, if needed. 748 HideDivsIfAllEmpty('search_event_image'); // Hide some empty columns, if needed. 749 750 // If we have been sent to the search page explicitly then prepare the page for searching. 751 var SearchBox = SystemSlice.find('input[id$="_txtSearchStringTemplate"]'); 752 if (SearchBox.length === 1) { 753 if (SearchBox.val() === 'Activate_Search') { 754 SystemSlice.find('h2').hide(); // hide the search result titles 755 SearchBox.val(''); // Clear the search text box 756 SearchBox.attr('placeholder','Type your search text here'); 757 SearchBox.attr("autocomplete","off"); 758 MediaControls.show(); // make the search controls show. 759 } 760 } 761 } else { 762 SystemSlice.find('ul.media_recording_details li:nth-child(2)').each(function(){ 763 var T = $(this); 764 var S = T.text().replace('Recorded: ',''); 765 var H = '<div class="MobileRecorded">' + S + '</div>'; 766 $(H).insertAfter(T.parent().parent().prev().children('div.media_recording_descr')); 767 }); 768 } 769 } 770 771 // Fix calendar mobile page. Add a class to days we want to hide on the mobile/list view. 772 if (PageType === '_calendar_month_aspx') { 773 var C = SystemSlice.find('select.group-selector'); 774 var H = SystemSlice.find('div#calendar_header'); 775 C.insertAfter(H.children().eq(0)); 776 $('<div class="Line"></div>').insertAfter(H.children().eq(1)); 777 var S = SystemSlice.find('span.calendar_children_select'); 778 S.insertAfter(H.children().eq(2)); 779 } 780 781} // end of bOnHomePage or bOnSystemPage if-block 782 783// Sort out login/logout/register/web-office links 784var SB = BodyTag.find('div.HiddenStatusBar'); 785if (SB.length === 1) { 786 if (bUserLoggedIn) { 787 var bWebOfficeActive = (SB.find('a.weboffice_link').length === 1); 788 if (!bWebOfficeActive) { // Need to hide WO links. 789 BodyTag.find('header a[href="/admin"]').hide(); 790 BodyTag.find('header a[href="/Admin/Default.aspx"]').hide(); 791 BodyTag.find('section.slice_FixedSideLinks a[href="/admin"]').hide(); 792 } 793 } else { 794 var SBRL = SB.find('a.register_link'); 795 if (SBRL.length === 0) { // Need to hide the register links. Need TWO versions for case changes. 796 BodyTag.find('header a[href="/User/Registration.aspx"]').hide(); 797 BodyTag.find('header a[href="/user/registration.aspx"]').hide(); 798 BodyTag.find('section.slice_FixedSideLinks a[href="/User/Registration.aspx"]').hide(); 799 BodyTag.find('section.slice_FixedSideLinks a[href="/user/registration.aspx"]').hide(); 800 } else { 801 var RegLink = SBRL.attr('href'); 802 if (RegLink !== "/User/Registration.aspx") { 803 BodyTag.find('header a[href="/User/Registration.aspx"]').attr('href',RegLink); 804 BodyTag.find('header a[href="/user/registration.aspx"]').attr('href',RegLink); 805 BodyTag.find('section.slice_FixedSideLinks a[href="/User/Registration.aspx"]').attr('href',RegLink); 806 BodyTag.find('section.slice_FixedSideLinks a[href="/user/registration.aspx"]').attr('href',RegLink); 807 } 808 } 809 } 810} 811 812// Fix Footer 813var LW = BodyTag.find('footer div.LogoWrapper'); 814 if(LW.length === 0){ 815 var FSG = BodyTag.find('footer div.FooterSafeGuarding'); 816 if(FSG.length === 1){ 817 FSG.addClass('BottomBorder'); 818 } 819 } 820 821// Fix the cookies slice 822HeaderSlice = BodyTag.find('header'); 823var CS = HeaderSlice.find('div.slice_Cookies'); 824 if (CS.length === 1) { 825 var IMG = CS.find('img'); 826 IMG.attr('src','/Images/Content/2823/Templates/56063/images/IconClose.png'); 827 IMG.click(function(){ 828 HeaderSlice.removeClass('HasCookieBar'); 829 }); 830 HeaderSlice.addClass('HasCookieBar'); 831 } 832
833// Sticky header 834// We need iYforHeaderTintDown - iYforHeaderTintUp to be larger than the difference between heights 835// for the large and small headers. 836var bHeaderTintOn = false, iYforHeaderTintDown = 50, iYforHeaderTintUp = 2; 837function PollScrollDownChanges() { // This routine must be very streamlined. Called every 250ms. 838 839 var iY = window.pageYOffset; 840 841 if (!bHeaderTintOn && iY >= iYforHeaderTintDown) { 842 if (window.innerWidth > 991) { // only apply if screen is of desktop size. 843 HeaderSlice.addClass('HeaderSmall'); 844 bHeaderTintOn = true; 845 } 846 } 847 if (bHeaderTintOn && iY < iYforHeaderTintUp) { 848 HeaderSlice.removeClass('HeaderSmall'); 849 bHeaderTintOn = false; 850 } 851} 852 853// If the screen is resized, then we have to click shut the SlickNav Menu, if it is open. 854var iLastWidth = 0; 855function ShutSlickNav() { 856 var iWidth = window.innerWidth; 857 if (iWidth !== iLastWidth) { // don't run code if it looks like we just have the browser top menu appearing and disappearing. 858 iLastWidth = iWidth; 859 if (bDesktopScreenPossible) { 860 if (SlickNavBtn.hasClass('slicknav_open')){ 861 SlickNavBtn.click(); 862 } 863 if (bOnHomePage && iWidth < 992 && HeaderSlice.hasClass('HeaderSmall')) { 864 HeaderSlice.removeClass('HeaderSmall'); 865 bHeaderTintOn = false; 866 } 867 } 868 } 869} 870 871window.addEventListener("resize", function(){ShutSlickNav();}, false); 872if (bDesktopScreenPossible) { 873 window.setInterval(function(){PollScrollDownChanges();}, 100); // poll to see if user has scrolled down. 874} 875 876// SlickNav poll - for the top level, when you open a sub-menu up, the others close up. 877var SL = BodyTag.find('header ul.slicknav_nav'); 878var LI = SL.children('li.slicknav_parent'); // these are the only top-links with a sub-menu 879var iOpen = -1; 880var iOpenMax = LI.length - 1; 881var bSwitch = true; 882LI.eq(0).click(function(){if(bSwitch){iOpen=0;}}); 883LI.eq(1).click(function(){if(bSwitch){iOpen=1;}}); 884LI.eq(2).click(function(){if(bSwitch){iOpen=2;}}); 885LI.eq(3).click(function(){if(bSwitch){iOpen=3;}}); 886LI.eq(4).click(function(){if(bSwitch){iOpen=4;}}); 887LI.eq(5).click(function(){if(bSwitch){iOpen=5;}}); 888LI.eq(6).click(function(){if(bSwitch){iOpen=6;}}); 889LI.eq(7).click(function(){if(bSwitch){iOpen=7;}}); 890LI.eq(8).click(function(){if(bSwitch){iOpen=8;}}); 891LI.eq(9).click(function(){if(bSwitch){iOpen=9;}}); 892LI.eq(10).click(function(){if(bSwitch){iOpen=10;}}); 893LI.eq(11).click(function(){if(bSwitch){iOpen=11;}}); // enough code for 12 sub-menus. 894 895 function SlickNavPoll() { 896 if(iOpen !== -1){ 897 var i; 898 for (i = 0; i <= iOpenMax; i++) { 899 if(i !== iOpen){ 900 if(LI.eq(i).hasClass('slicknav_open')){ 901 bSwitch = false; 902 LI.eq(i).children('a').click(); 903 bSwitch = true; 904 } 905 } 906 } // end for 907 } 908 } 909window.setInterval(function(){SlickNavPoll();}, 250); 910 911});
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.