1/* JS for preset "Menu V2" */ 2(function() { 3 $(function() { 4 $('.menu-wrapper').each(function() { 5 initMenu($(this)) 6 }); 7 }); 8 9 // Make :active pseudo classes work on iOS 10 document.addEventListener("touchstart", function() {}, false); 11 12 var initMenu = function($menuWrapper) { 13 var $body = $('body'); 14 var $menu = $('.ed-menu', $menuWrapper); 15 var $menuLinks = $('a', $menu); 16 var $menuTrigger = $('.menu-trigger', $menuWrapper); 17 var $banner = $('.banner').first(); 18 19 var menuWrapperHeight = $menuWrapper.outerHeight(); 20 var bannerHeight = $banner.length ? $banner.outerHeight() : 0; 21 var smoothScrollOffset = 20; 22 23 toggleClassOnClick($body.add($menu), $menuTrigger, null, 'open open-menu'); // Keep open on $menu for backward compatibility 24 activateSmoothScroll($menuLinks.add($('.scroll a')), smoothScrollOffset); 25 addClassOnVisibleLinkTargets($menuLinks, 'active', 2 / 3); 26 handleSticky($menuWrapper, 'sticky', $banner); 27 }; 28 29 /** 30 * Observe element's height changes and reload the initMenu() function 31 * 32 * @param {HTMLElement} elm Element to observe 33 * @param {function} callback to call when elmement's height changed 34 */ 35 var observeHeightChange = function(elm, callback) { 36 if (!('ResizeObserver' in window) || elm == null) return; 37 38 var ro = new ResizeObserver(callback); 39 ro.observe(elm); 40 } 41 42 /** 43 * Toggles class on a target when a trigger is clicked 44 * 45 * @param {jQuery} $target The target to apply the CSS class to 46 * @param {jQuery} $trigger The Trigger 47 * @param {jQuery} $closeTrigger Optional close trigger 48 * @param {string} cssClass CSS Class to toggle on the target 49 */ 50 var toggleClassOnClick = function($target, $trigger, $closeTrigger, cssClass) { 51 52 // Reset in case class "open" was saved accidentally 53 $target.removeClass(cssClass); 54 $trigger.removeClass(cssClass); 55 56 // Click on trigger toggles class "open" 57 $trigger.off('.toggle').on('click.toggle', function() { 58 $(this).toggleClass(cssClass); 59 $target.toggleClass(cssClass); 60 }); 61 62 // Close target when link inside is clicked 63 $target.find('a').click(function() { 64 $target.removeClass(cssClass); 65 $trigger.removeClass(cssClass); 66 }); 67 68 if (!$closeTrigger || !$closeTrigger.length) { 69 return; 70 } 71 72 $closeTrigger.click(function() { 73 $target.removeClass(cssClass); 74 $trigger.removeClass(cssClass); 75 }); 76 }; 77 78 /** 79 * Smooth scroll to link targets 80 * 81 * @param {jQuery} $scrollLinks The links 82 * @param {jQuery} scrollOffset Offset to subtract from the scroll target position (e.g. for fixed positioned elements like a menu) 83 */ 84 var activateSmoothScroll = function($scrollLinks, scrollOffset) { 85 if (typeof scrollOffset === 'undefined') { 86 scrollOffset = 0; 87 } 88 89 var determineTarget = function($trigger, hash) { 90 if (hash == '#!next') { 91 return $trigger.closest('.ed-element').next(); 92 } 93 94 return $(hash); 95 } 96 97 $scrollLinks.click(function(e) { 98 var $target = determineTarget($(this), this.hash); 99 if (!$target.length) return; 100 e.preventDefault(); 101 102 viewport.scrollTo($target, 'top', 500, 0); 103 104 }); 105 }; 106 107 /** 108 * We are using the fill property on an element to pass user's choices from CSS to JavaScript 109 * 110 * @param {jQuery} $element 111 */ 112 var getStickyMode = function($element) { 113 var fillValue = getComputedStyle($element[0]).fill; 114 115 return fillValue === 'rgb(255, 0, 0)' ? 116 'sticky_banner' : 117 fillValue === 'rgb(0, 255, 0)' ? 118 'sticky_menu' : 119 fillValue === 'rgb(0, 0, 255)' ? 120 'sticky_instant' : 121 fillValue === 'rgb(255, 255, 255)' ? 122 'sticky_reverse' : 123 'sticky_none'; 124 }; 125 126 /** 127 * Adds a class to an element when not currently visible 128 * 129 * @param {jQuery} $element The element to handle stickyness for 130 * @param {string} cssClass The actual CSS class to be applied to the element when it's above a certain scroll position 131 * @param {jQuery} $banner A banner to reference the scroll position to 132 */ 133 var handleSticky = function($element, cssClass, $banner) { 134 var triggerPos = 0, 135 offset = 0; 136 var menuWrapperHeight = $element.outerHeight(); 137 var mode; 138 var prevScroll = 0; 139 $element.removeClass(cssClass); 140 141 var toggleSpacer = function(toggle) { 142 document.body.style.setProperty('--spacer-height', toggle ? menuWrapperHeight + 'px' : ''); 143 }; 144 145 var handleScroll = function() { 146 if (!$element.length || mode === 'sticky_none') return; 147 148 var isReverse = mode === 'sticky_reverse', 149 curScroll = viewport.getScrollTop(); 150 151 if (triggerPos <= curScroll && (!isReverse || prevScroll > curScroll)) { 152 $element.addClass(cssClass); 153 toggleSpacer(true); 154 } else { 155 $element.removeClass(cssClass); 156 toggleSpacer(false); 157 } 158 159 prevScroll = curScroll; 160 }; 161
162 var updateOffset = function() { 163 mode = getStickyMode($element); 164 menuWrapperHeight = $element.outerHeight(); 165 if (!$element.hasClass(cssClass)) { 166 offset = $element.offset().top; 167 } 168 if (mode === 'sticky_banner' && !$banner.length) { 169 mode = 'sticky_menu'; 170 } 171 if (mode === 'sticky_banner') { 172 triggerPos = $banner.offset().top + ($banner.length ? $banner.outerHeight() : $element.outerHeight()); 173 } 174 if (mode === 'sticky_menu' || mode === 'sticky_reverse') { 175 triggerPos = offset + $element.outerHeight(); 176 } 177 if (mode === 'sticky_instant') { 178 triggerPos = offset; 179 } 180 181 handleScroll(); 182 } 183 184 viewport.observe('resize', updateOffset); 185 viewport.observe('animation.end', updateOffset); 186 observeHeightChange($element[0], updateOffset); 187 updateOffset(); 188 189 viewport.observe('scroll', handleScroll); 190 handleScroll(); 191 }; 192 193 /** 194 * Adds a class to links whose target is currently inside the viewport 195 * 196 * @param {jQuery} $links Link(s) to be observed 197 * @param {string} cssClass CSS Class to be applied 198 * @param {float} sectionViewportRatio Ratio by which the target should be within the viewport 199 */ 200 var addClassOnVisibleLinkTargets = function($links, cssClass, sectionViewportRatio) { 201 if (typeof sectionViewportRatio === 'undefined') { 202 sectionViewportRatio = 1 / 2; 203 } 204 205 var menuTargets = []; 206 var activeLink = $links.filter('.active:not(.wv-link-elm)').eq(0); 207 208 var links = $links.filter(function() { 209 var $target = $(this.hash); 210 if (!$target.length) { 211 return false; 212 } 213 214 // Cache offset position to improve performance (update on resize) 215 var updateOffset = function() { 216 $target.data('offset', $target.offset().top); 217 }; 218 219 viewport.observe('resize', updateOffset); 220 viewport.observe('animation.end', updateOffset); 221 updateOffset(); 222 223 menuTargets.push($target); 224 return true; 225 }); 226 227 // No hash links found, so don't handle it at all 228 if (!links.length) { 229 return; 230 } 231 232 var checkVisibility = function() { 233 $links.removeClass('active'); 234 235 // Check section position reversely 236 for (var i = menuTargets.length - 1; i >= 0; i--) { 237 var desiredScrollPosition = menuTargets[i].data('offset') - viewport.getHeight() * (1 - sectionViewportRatio); 238 if (viewport.getScrollTop() >= desiredScrollPosition && menuTargets[i][0].offsetParent !== null) { 239 links.eq(i).addClass(cssClass); 240 return; 241 } 242 } 243 244 // Fallback to originally active item 245 activeLink.addClass(cssClass); 246 }; 247 248 viewport.observe('scroll', checkVisibility); 249 checkVisibility(); 250 }; 251})(); 252/* End JS for preset "Menu V2" */ 253 254/* JS for preset "Cookie Consent Bar V3" */ 255$(function() { 256 $('#cookieClose').click(function(e) { 257 e.preventDefault(); 258 createCookie('cookieConsentBar', "rejected", 0.5); 259 $('.cookie-consent-bar').hide(); 260 261 // If inside of an overlay, close it too 262 if ($('.cookie-consent-bar').closest('.mfp-content').length) { 263 $.magnificPopup.close(); 264 return; 265 } 266 }); 267 268 $('#acceptCookie').click(function(e) { 269 e.preventDefault(); 270 createCookie('cookieConsentBar', "accepted", 0.5); 271 $('.cookie-consent-bar').hide(); 272 273 if (typeof ThirdPartyScripts !== "undefined") { 274 ThirdPartyScripts.unblock(); 275 } 276 277 // If inside of an overlay, close it too 278 if ($('.cookie-consent-bar').closest('.mfp-content').length) { 279 $.magnificPopup.close(); 280 return; 281 } 282 }); 283 284 var preview = false; 285 286 var listener = function() { 287 if (!preview && document.body.classList.contains('preview')) { 288 console.log("entering preview"); 289 preview = true; 290 } else if (preview && !document.body.classList.contains('preview')) { 291 console.log("leaving preview"); 292 $('.cookie-consent-bar').show(); 293 preview = false; 294 } 295 requestAnimationFrame(listener); 296 }; 297 298 requestAnimationFrame(listener); 299 300 if (document.body.classList.contains('edit') || document.body.classList.contains('preview')) { 301 return; 302 } 303 304 305 // Cookie bar 306 if (readCookie('cookieConsentBar') == "accepted") { 307 $('.cookie-consent-bar').hide(); 308 window.setTimeout(function() { 309 if (typeof ThirdPartyScripts !== "undefined") { 310 ThirdPartyScripts.unblock(); 311 } 312 }, 100); 313 } else if (readCookie('cookieConsentBar') == "rejected") { 314 $('.cookie-consent-bar').hide(); 315 } else { 316 $('.cookie-consent-bar').show(); 317 } 318 319 function readCookie(name) { 320 var nameEQ = name + "="; 321 var ca = document.cookie.split(';'); 322 for (var i = 0; i < ca.length; i++) { 323 var c = ca[i]; 324 while (c.charAt(0) == ' ') c = c.substring(1, c.length); 325 if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length); 326 } 327 return null; 328 } 329 330 function createCookie(name, value, days) { 331 if (days) { 332 var date = new Date(); 333 date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); 334 var expires = "; expires=" + date.toGMTString(); 335 } else expires = ""; 336 document.cookie = name + "=" + value + expires + "; path=/"; 337 } 338 339 // Fix for hiding Content till page is loaded 340 $(document).ready(function() { 341 $('.hide-cookie-content').removeClass("hide-cookie-content"); 342 }); 343}); 344/* End JS for preset "Cookie Consent Bar V3" */
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.