1(function() { 2 3 var navToggle = document.querySelector('.nav-toggle'); 4 var searchToggle = document.querySelector('.search-toggle'); 5 var navContent = document.querySelector('.header-navigation'); 6 var body = document.querySelector('body'); 7 var html = document.querySelector('html'); 8 var htmlStyle = html.currentStyle || window.getComputedStyle(html); 9 var htmlMarginTop = htmlStyle.marginTop; 10 var menuItemsWithChildren = document.querySelectorAll('.menu-item-has-children > a'); 11 var menuItems = document.querySelectorAll('.navigation-wrapper a, .logo a, a.get-started-h, a.login'); 12 var footerItems = document.querySelectorAll('.site-footer a'); 13 var links = document.querySelectorAll('.site-main a:not([data-placement])'); 14 var downloads = document.querySelectorAll('.type-download .actions a'); 15 var selects = document.querySelectorAll('.select'); 16 var spacers = document.querySelectorAll('.fav-spacer'); 17 var secondaryMenu = document.querySelector('.secondary-menu h3'); 18 var searchInputs = document.querySelectorAll('.search-field'); 19 var searchButtons = document.querySelectorAll('.search-submit'); 20 var searchClose = document.querySelector('#search-results .icon-close'); 21 var searchTimeout = null; 22 var mixButtons = document.querySelectorAll('[data-placement]'); 23 24 if(window.innerHeight < 1200) { 25 document.getElementById('masthead').style.position = 'static'; 26 document.getElementById('masthead').style.position = 'static'; 27 } 28 29 if(searchClose) { 30 searchClose.addEventListener('click', function(event) { 31 body.classList.remove('search-active'); 32 }); 33 } 34 35 if(searchInputs) { 36 searchInputs.forEach(input => { 37 input.addEventListener('keyup', function(e) { 38 if (e.key == "Enter") { 39 e.preventDefault(); 40 ajaxSearch(input); 41 } else if(input.value.length > 3) { 42 clearTimeout(searchTimeout); 43 searchTimeout = setTimeout( function(){ 44 ajaxSearch(input) 45 }, 1000); 46 } 47 }); 48 }); 49 } 50 51 if(searchButtons) { 52 searchButtons.forEach(button => { 53 button.addEventListener('click', function(event) { 54 event.preventDefault(); 55 }); 56 }); 57 } 58 59 if(secondaryMenu) { 60 secondaryMenu.addEventListener('click', function(event) { 61 secondaryMenu.classList.toggle('active'); 62 secondaryMenu.nextElementSibling.classList.toggle('active'); 63 }); 64 } 65 66 spacers.forEach(spacer => { 67 var skip = [ 68 'SCRIPT', 69 ]; 70 var element = spacer.previousElementSibling; 71 while(element && skip.includes(element.tagName)) { 72 element = element.previousElementSibling; 73 } 74 if(element) { 75 element.style.marginBottom = 0; 76 } 77 78 element = spacer.nextElementSibling; 79 while(element && skip.includes(element.tagName)) { 80 element = element.nextElementSibling; 81 } 82 if(element) { 83 element.style.marginTop = 0; 84 } 85 }); 86 87 selects.forEach(item => { 88 item.querySelector('.icon-down').addEventListener('click', function(event) { 89 item.querySelector('select').click(); 90 }); 91 }); 92 93 // TODO split to functions or files (mobile vs desktop) 94// if(window.innerWidth < favTheme.mobileBreakpoint) { 95 menuItemsWithChildren.forEach(item => { 96 item.addEventListener('click', function(event) { 97// if(event.target.nodeName == 'SPAN') { 98// return; 99// } 100 event.preventDefault(); 101 var element = event.target.closest('.menu-item-has-children'); 102 if(element.classList.contains('active') || element.classList.contains('current-menu-parent')) { 103 element.classList.remove('active'); 104 element.classList.remove('current-menu-parent'); 105 } else { 106 document.querySelectorAll('.menu-item-has-children > a').forEach(item2 => { 107 var element2 = item2.closest('.menu-item-has-children'); 108 element2.classList.remove('active'); 109 element2.classList.remove('current-menu-parent'); 110 }); 111 element.classList.add('active') 112 } 113 }); 114 }); 115 116// document.addEventListener('click', function (event) { 117// 118// // If the clicked element doesn't have the right selector, bail 119// if (!event.target.matches('.menu-item-has-children')) return; 120// 121// // Don't follow the link 122// event.preventDefault(); 123// 124// // Log the clicked element in the console
125// console.log(event.target); 126// 127// }, false); 128 129 navToggle.addEventListener('click', function (event) { 130 event.preventDefault(); 131 event.stopPropagation(); 132 if(navToggle.classList.contains('active')) { 133 menuHide(); 134 } else { 135 menuShow(); 136 } 137 }); 138 139 searchToggle.addEventListener('click', function (event) { 140 event.preventDefault(); 141 event.stopPropagation(); 142 showSearchResults([], 'header search'); 143 }); 144 145 146 function menuShow() { 147 navToggle.classList.add('active'); 148 navToggle.classList.remove('icon-menu'); 149 navToggle.classList.add('icon-close'); 150 body.classList.add('menu-active'); 151 navToggle.innerHTML = '<span>Explore</span>'; 152 } 153 154 function menuHide() { 155 navToggle.classList.remove('active'); 156 navToggle.classList.remove('icon-close'); 157 navToggle.classList.add('icon-menu'); 158 body.classList.remove('menu-active'); 159 navToggle.innerHTML = '<span>Get started</span>'; 160 } 161 162 const handleMenuClosure = event => !navContent.contains(event.target) && menuHide() 163 164 window.addEventListener('click', handleMenuClosure) 165 window.addEventListener('focusin', handleMenuClosure) 166 167 function scrollingClass(event) { 168 var y = window.pageYOffset || document.documentElement.scrollTop; 169 if(y === 0) { 170 document.body.classList.remove('scrolling'); 171 } else { 172 document.body.classList.add('scrolling'); 173 } 174 } 175 176 function ajaxSearch(input) { 177 var placement = input.parentElement.getAttribute('aria-label').indexOf("blog") != -1 ? "blog" : "header"; 178 var query = input.value; 179 var post_type = input.dataset.postType; 180 const params = new URLSearchParams({ 181 action: "fav_search", 182 query: query, 183 post_type: post_type, 184 }); 185 fetch(favTheme.adminAjax + '?' + params.toString(), { 186 method: 'GET', 187 headers: { 188 'Content-Type': 'application/json' 189 }, 190 referrer: 'no-referrer' 191 }).then(function (response) { 192 193 // The API call was successful! 194 if (response.ok) { 195 return response.json(); 196 } 197 198 // There was an error 199 return Promise.reject(response); 200 201 }).then(function (data) { 202 // This is the JSON from our response 203 if(data.success) { 204 showSearchResults(data.data, placement); 205 if(mixpanel) { 206 mixpanel.track( 207 "Search Completed", 208 { 209 "query": query, 210 "placement": placement 211 } 212 ); 213 } 214 } 215 }).catch(function (err) { 216 // There was an error 217 console.warn('Something went wrong.', err); 218 }); 219 } 220 221 function showSearchResults(data, placement=null) { 222 if(!body.classList.contains('search-active')) { 223 body.classList.add('search-active'); 224 } 225 document.querySelector('#search-results input').focus(); 226 if(placement) { 227 document.querySelector('#search-results form').setAttribute('aria-label', placement); 228 } 229 if(data) { 230 if(data.query) { 231// document.querySelector('#search-results input').value = data.query; 232 } 233 if(data.results) { 234 var results = document.getElementById('search-results-posts'); 235 results.parentElement.classList.add('active'); 236 results.innerHTML = 'test'; 237 var html = ''; 238 data.results.forEach(row => { 239 html += '<div class="result type-' + row.type + '">'; 240 html += row.icon; 241 html += '<h4>' + row.title + '</h4>'; 242 html += '<div class="h4 lexia">' + row.excerpt + '</div>'; 243 html += '<div class="actions"><a href="'+ row.link +'" class="button link">Read More<i class="icon-arrow-next"></i></a></div>'; 244 html += '</div>'; 245 }); 246 results.innerHTML = html; 247 if(mixpanel) { 248 results.querySelectorAll('.button.link')?.forEach((link)=>{ 249 link.addEventListener('click',(event)=>{ 250 mixpanel.track( 251 "CTA click", 252 { 253 // "destination" : button.getAttribute('href'), 254 "destination_Url" : link.getAttribute('href'), 255 "placement" : placement, 256 "text" : link.textContent, 257 "type" : "button", 258 // "Location" : button.closest('section').className.replace(/fa-block|.[^\s]*width[^\s]*|\sshape[^\s$]*/, ''), 259 // "url" : location.href, 260 "source_Url" : location.href 261 } 262 ); 263 }) 264 }) 265 } 266 } else { 267 var results = document.getElementById('search-results-posts'); 268 results.parentElement.classList.remove('active'); 269 } 270 } else { 271 document.querySelector('#search-results input').dataset.postType = 'any' 272 } 273 } 274 275 const numSteps = 20.0; 276 277 let increasingColor = "rgba(40, 40, 190, ratio)"; 278 let decreasingColor = "rgba(190, 40, 40, ratio)"; 279 let animationTargets = document.querySelectorAll('.fav-block[class*="shape-"]:not([class*="-top-"]):not([class*="-bottom-"]) .graphic'); 280 281 // Set things up 282 window.addEventListener("load", (event) => { 283 284 createObserver(); 285 }, false); 286 287 function createObserver() { 288 let observer; 289 290 let options = { 291 root: null, 292 rootMargin: "0px", 293 threshold: buildThresholdList() 294 }; 295 296 observer = new IntersectionObserver(handleIntersect, options);
297 animationTargets.forEach(target => { 298 observer.observe(target); 299 }); 300 } 301 302 function buildThresholdList() { 303 let thresholds = []; 304 let numSteps = 20; 305 306 for (let i=1.0; i<=numSteps; i++) { 307 let ratio = i/numSteps; 308 thresholds.push(ratio); 309 } 310 311 thresholds.push(0); 312 return thresholds; 313 } 314 315 function handleIntersect(entries, observer) { 316 entries.forEach((entry) => { 317 var prevRatio = entry.target.dataset.prevRatio; 318 if(typeof prevRatio == 'undefined') { 319 prevRatio = 0.0; 320 } 321 entry.target.style.opacity = entry.intersectionRatio; 322 entry.target.dataset.prevRatio = entry.intersectionRatio; 323 }); 324 } 325 326 // The parallax function 327 const parallax = elements => { 328 if ('undefined' !== elements && elements.length > 0) { 329 elements.forEach( element => { 330 let y = window.innerHeight - document.getElementById('masthead').offsetHeight - element.getBoundingClientRect().top 331// if(element.parentElement.className.includes('fixed')) { 332// return; 333// } 334 if (y > 0) { 335// console.log(y + ' : ' + (0.25 * y)); 336 element.style.transform = 'translate3d(0, ' + (0.1 * y) + 'px ,0)' 337 } 338 }) 339 } 340 } 341 342 //If element is in viewport, set its position 343 parallax(animationTargets) 344 345 //Call the function on scroll 346 window.onscroll = () => { 347 parallax(animationTargets) 348 } 349 350 window.addEventListener('scroll', scrollingClass); 351 scrollingClass(); 352 353 if(menuItems) { 354 menuItems.forEach(anchor => { 355 anchor.addEventListener('click', function(event) { 356 if(mixpanel) { 357 mixpanel.track( 358 "Nav Clicked", 359 { 360 "destination_Url" : anchor.getAttribute('href'), 361 "Text" : anchor.textContent, 362 "Source_Url" : location.href, 363 "Type" : "main menu", 364 } 365 ); 366 } 367 }); 368 }) 369 } 370 if(footerItems) { 371 footerItems.forEach(anchor => { 372 anchor.addEventListener('click', function(event) { 373 if(mixpanel) { 374 event.preventDefault() 375 var a = new RegExp('/' + window.location.host + '/'); 376 console.log('Footer click') 377 if (a.test(anchor.getAttribute('href'))) { 378 mixpanel.track( 379 "Nav Clicked", 380 { 381 "destination_Url" : anchor.getAttribute('href'), 382 "Text" : anchor.textContent, 383 "Source_Url" : location.href, 384 "Type" : "bottom menu", 385 } 386 ); 387 location.href = anchor.getAttribute('href') 388 } else { 389 mixpanel.track( 390 "Link Clicked", 391 { 392 "destination_Url" : anchor.getAttribute('href'), 393 "Text" : anchor.textContent, 394 "source_Url" : location.href 395 } 396 ); 397 setTimeout(function(){ 398 location.href = anchor.getAttribute('href') 399 }, 400) 400 } 401 } 402 }); 403 }) 404 } 405 if(links) { 406 links.forEach(anchor => { 407 anchor.addEventListener('click', function(event) { 408 if(mixpanel) { 409 var a = new RegExp('/' + window.location.host + '/'); 410 if (!a.test(anchor.getAttribute('href'))) { 411 event.preventDefault() 412 mixpanel.track( 413 "Link Clicked", 414 { 415 "destination_Url" : anchor.getAttribute('href'), 416 "Text" : anchor.textContent, 417 "source_Url" : location.href 418 } 419 ); 420 location.href = anchor.getAttribute('href') 421 } 422 } 423 }); 424 }) 425 } 426 if(mixButtons) { 427 mixButtons.forEach(button => { 428 button.addEventListener('click', function(event) { 429// event.preventDefault(); 430 var placement = button.dataset.placement; 431 if(mixpanel) { 432 mixpanel.track( 433 "CTA click", 434 { 435 // "destination" : button.getAttribute('href'), 436 "destination_Url" : button.getAttribute('href'), 437 "placement" : placement, 438 "text" : button.textContent, 439 "type" : "button", 440 // "Location" : button.closest('section').className.replace(/fa-block|.[^\s]*width[^\s]*|\sshape[^\s$]*/, ''), 441 // "url" : location.href, 442 "source_Url" : location.href 443 } 444 ); 445 } 446 }); 447 }) 448 } 449 if(downloads) { 450 downloads.forEach(button => { 451 button.addEventListener('click', function(event) { 452// event.preventDefault(); 453 var placement = button.dataset.placement; 454 if(mixpanel) { 455 mixpanel.track( 456 "File Downloaded", 457 { 458 "file_name" : button.getAttribute('href').split('/').pop(), 459 "file_type" : button.getAttribute('href').split('.').pop(), 460 "file_url" : button.getAttribute('href'), 461 "source_url" : location.href 462 } 463 ); 464 } 465 }); 466 }) 467 } 468 469})(); 470 471document.addEventListener("DOMContentLoaded", function() { 472 function handleSelectChange(event) { 473 let selectedValue = event.target.value; 474 if (selectedValue) { 475 window.location.href = selectedValue; // Redirect to the selected category or tag archive 476 } 477 } 478 479 document.getElementById("category-select")?.addEventListener("change", handleSelectChange); 480 document.getElementById("tag-select")?.addEventListener("change", handleSelectChange); 481}); 482 483document.addEventListener("DOMContentLoaded", (event) => { 484 gsap.registerPlugin(ScrollTrigger) 485 // gsap code here! 486 console.log('gsap') 487 gsap.from('.blog-hero h1', { 488 scrollTrigger: '.blog-hero h1', 489 opacity: 0, 490 y: 50, 491 ease: "power1.out", 492 }); 493 gsap.from('.blog-hero .h3', { 494 scrollTrigger: '.blog-hero .h3', 495 opacity: 0, 496 y: 50, 497 delay: 0.2, 498 ease: "power1.out", 499 }); 500 gsap.from('.filter-form', { 501 scrollTrigger: '.filter-form', 502 opacity: 0, 503 y: 50, 504 delay: 0.4, 505 ease: "power1.out", 506 });
507 let cardDelay = 0 508 document.querySelectorAll('.post-card')?.forEach((card)=>{ 509 gsap.from(card, { 510 scrollTrigger: card, 511 opacity: 0, 512 y: 50, 513 delay: cardDelay, 514 ease: "power1.out", 515 }); 516 cardDelay+= 0.1 517 }) 518});
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.