1'use strict'; 2/* 3 * Opt in (e.g. EU): 4 * default all scripts disabled. 5 * cookie banner 6 * 7 * Opt out (e.g. US): 8 * default all scripts enabled 9 * opt out cookie banner 10 * 11 * Other regions: 12 * default all scripts enabled 13 * no banner 14 * 15 * 16 * For examples to edit the behaviour of the banner, please see https://github.com/really-Simple-Plugins/complianz-integrations 17 * */ 18 19/* 20 * Create an element 21 * @param el 22 * @param content 23 * @returns {*} 24 */ 25function cmplz_create_element(el, content) { 26 let obj = document.createElement(el); 27 obj.innerHtml = content; 28 return obj; 29} 30 31/* 32 * Add an event 33 * @param event 34 * @param selector 35 * @param callback 36 * @param context 37 */ 38function cmplz_add_event(event, selector, callback ) { 39 document.addEventListener(event, e => { 40 if ( e.target.closest(selector) ) { 41 callback(e); 42 } 43 }); 44} 45 46/* 47 * Check if the element is hidden 48 * @param el 49 * @returns {boolean} 50 */ 51function cmplz_is_hidden(el) { 52 return (el.offsetParent === null) 53} 54 55function cmplz_html_decode(input) { 56 var doc = new DOMParser().parseFromString(input, "text/html"); 57 return doc.documentElement.textContent; 58} 59/* 60 * If an anchor is passed for an element which may load only after an ajax call, make sure it will scroll into view. 61 */ 62document.addEventListener('cmplz_manage_consent_container_loaded', function(e){ 63 let url = window.location.href; 64 if ( url.indexOf('#') != -1 ) { 65 let end_pos = url.lastIndexOf("?") != -1 ? url.lastIndexOf("?") : undefined; 66 var anchor = url.substring(url.indexOf("#") + 1, end_pos); 67 const element = document.getElementById(anchor); 68 if (element) { 69 const y = element.getBoundingClientRect().top + window.pageYOffset - 200; 70 window.scrollTo({top: y, behavior: 'smooth'}); 71 } 72 } 73}); 74 75/* 76 * prevent caching of the WP Rest API by varnish or other caching tools 77 */ 78complianz.locale = complianz.locale + '&token='+Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5); 79 80/* 81 * CustomEvent() polyfill 82 * https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill 83 */ 84(function () { 85 if (typeof window.CustomEvent === 'function') return false; 86 function CustomEvent(event, params) { 87 params = params || { bubbles: false, cancelable: false, detail: undefined }; 88 var evt = document.createEvent('CustomEvent'); 89 evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); 90 return evt; 91 } 92 CustomEvent.prototype = window.Event.prototype; 93 window.CustomEvent = CustomEvent; 94})(); 95 96let cmplz_banner;//look this one up when the cookiebanner loads. 97let cmplz_banner_container = document.getElementById('cmplz-cookiebanner-container'); 98let cmplz_manage_consent_button; 99let cmplz_waiting_inline_scripts = []; 100let cmplz_waiting_scripts = []; 101let cmplz_fired_scripts = []; 102let cmplz_placeholder_class_index = 0; 103let cmplz_all_scripts_hook_fired = false; 104let cmplz_consent_stored_once = false; 105let cmplz_categories = [ 106 'functional', 107 'preferences', 108 'statistics', 109 'marketing', 110]; 111 112/* 113 * Get a cookie by name 114 * @param name 115 * @returns {string} 116 */ 117 118window.cmplz_get_cookie = function (name) { 119 if (typeof document === "undefined") { 120 return ""; 121 } 122 name = complianz.prefix + name; 123 const value = "; " + document.cookie; 124 const parts = value.split("; " + name + "="); 125 if ( parts.length === 2 ) { 126 return parts.pop().split(";").shift(); 127 } 128 129 return ""; 130}; 131 132/* 133 * set a cookie 134 * @param name 135 * @param value 136 * @param use_prefix 137 */ 138 139window.cmplz_set_cookie = function(name, value, use_prefix) { 140 if (typeof document === 'undefined') { 141 return; 142 } 143 if (typeof use_prefix === 'undefined') { 144 use_prefix = true; 145 } 146 let secure = ";secure"; 147 let date = new Date(); 148 date.setTime(date.getTime() + (complianz.cookie_expiry * 24 * 60 * 60 * 1000)); 149 let expires = ";expires=" + date.toGMTString(); 150 151 if (window.location.protocol !== "https:") secure = ''; 152 153 let domain = cmplz_get_cookie_domain(); 154 if (domain.length > 0) { 155 domain = ";domain=" + domain; 156 } 157 let prefix = ''; 158 if ( use_prefix ) { 159 prefix = complianz.prefix; 160 } 161 document.cookie = prefix+name + "=" + value + ";SameSite=Lax" + secure + expires + domain + ";path="+cmplz_get_cookie_path(); 162} 163 164/* 165 * Check if needle occurs in the haystack 166 * @param needle 167 * @param haystack 168 * @returns {boolean} 169 */ 170window.cmplz_in_array = function(needle, haystack) { 171 let length = haystack.length; 172 for(let i = 0; i < length; i++) { 173 if(haystack[i] == needle) return true; 174 } 175 return false;
176} 177 178/* 179 * Retrieve the highest level of consent that has been given 180 * 181 * */ 182 183window.cmplz_highest_accepted_category = function() { 184 var consentedCategories = cmplz_accepted_categories(); 185 if (cmplz_in_array( 'marketing', consentedCategories )) { 186 return 'marketing'; 187 } 188 189 if (cmplz_in_array( 'statistics', consentedCategories )) { 190 return 'statistics'; 191 } 192 193 if (cmplz_in_array( 'preferences', consentedCategories )) { 194 return 'preferences'; 195 } 196 197 return 'functional'; 198} 199 200/* 201 * Accept all categories 202 */ 203window.cmplz_accept_all = function(){ 204 for (var key in cmplz_categories) { 205 if ( cmplz_categories.hasOwnProperty(key) ) { 206 cmplz_set_consent(cmplz_categories[key], 'allow'); 207 } 208 } 209} 210 211/* 212 * Sets all accepted categories as class in body 213 */ 214 215function cmplz_set_category_as_body_class() { 216 let classList = document.body.className.split(/\s+/); 217 for (let i = 0; i < classList.length; i++) { 218 if ( classList[i].indexOf('cmplz-') !== -1 && classList[i] !== 'cmplz-document' ) { 219 document.body.classList.remove( classList[i] ); 220 } 221 } 222 223 let cats = cmplz_accepted_categories(); 224 for (let i in cats) { 225 if ( cats.hasOwnProperty(i) ) { 226 document.body.classList.add('cmplz-' + cats[i]); 227 } 228 } 229 230 let services = cmplz_get_all_service_consents(); 231 for (let service in services) { 232 if ( services.hasOwnProperty(service) && services[service]) { 233 document.body.classList.add('cmplz-' + service); 234 } 235 } 236 237 document.body.classList.add('cmplz-' + complianz.region); 238 document.body.classList.add('cmplz-' + complianz.consenttype); 239 let event = new CustomEvent('cmplz_set_category_as_bodyclass'); 240 document.dispatchEvent(event); 241} 242 243function cmplz_append_css(css){ 244 let head = document.getElementsByTagName('head')[0]; 245 let style = document.createElement('style'); 246 style.setAttribute('type', 'text/css'); 247 if (style.styleSheet) { // IE 248 style.styleSheet.cssText = css; 249 } else { // the world 250 style.appendChild(document.createTextNode(css)); 251 } 252 head.appendChild(style); 253} 254 255function cmplz_load_css( path ) { 256 let targetObj = document.createElement("link") 257 targetObj.setAttribute("rel", "stylesheet") 258 targetObj.setAttribute("type", "text/css") 259 targetObj.setAttribute("href", path) 260 document.getElementsByTagName("head")[0].appendChild(targetObj) 261} 262 263/* 264 * Run script, src or inline 265 * @param script //src or inline script 266 * @param category 267 * @param type 268 */ 269 270function cmplz_run_script( script, category, type, sourceObj ) { 271 let targetObj = document.createElement("script"); 272 if ( type !== 'inline' ) { 273 targetObj.setAttribute("src", script); 274 } else { 275 if (typeof script !== 'string') { 276 script = script.innerHTML; 277 } 278 targetObj.innerHTML = [script, 'cmplzScriptLoaded();'].join('\n'); 279 } 280 //check if already fired 281 if ( cmplz_in_array( script, cmplz_fired_scripts) ) { 282 return; 283 } 284 285 cmplzCopyAttributes(sourceObj, targetObj); 286 287 try { 288 if (type!=='inline') { 289 targetObj.onload = function () { 290 cmplz_run_after_all_scripts(category); 291 cmplz_maybe_run_waiting_scripts(script, category, sourceObj); 292 } 293 } else { 294 window.cmplzScriptLoaded = function() { 295 cmplz_run_after_all_scripts(category); 296 cmplz_maybe_run_waiting_scripts(script, category, sourceObj); 297 } 298 } 299 let header = document.getElementsByTagName("head")[0]; 300 header.appendChild(targetObj); 301 302 } catch(exception) { 303 //only runs in case of error 304 cmplz_run_after_all_scripts(category); 305 throw "Something went wrong " + exception + " while loading "+script; 306 } 307 308} 309 310 311/* 312 * Check if there are waiting scripts, and if so, run them. 313 * @param script //src or inline script 314 * @param category 315 */ 316 317function cmplz_maybe_run_waiting_scripts( script, category, sourceObj ){ 318 let waitingScript = cmplz_get_waiting_script(cmplz_waiting_scripts, script); 319 if ( waitingScript ) { 320 cmplz_run_script( waitingScript, category, 'src', sourceObj ); 321 } 322 323 let waiting_inline_script = cmplz_get_waiting_script(cmplz_waiting_inline_scripts, script); 324 if (waiting_inline_script) { 325 cmplz_run_script(waiting_inline_script, category, 'inline', sourceObj); 326 } 327} 328 329/* 330 * Set placeholder image as background on the parent div, set notice, and handle height. 331 * 332 * */ 333 334function cmplz_set_blocked_content_container() { 335 //to prevent this function to twice run on an element, we add an attribute to each element that has been processed. 336 //then skip elements with that element. 337 document.querySelectorAll('.cmplz-image').forEach(obj => { 338 if ( obj.classList.contains('cmplz-processed') ) { 339 return; 340 } 341 obj.classList.add('cmplz-processed' ); 342 let service = obj.getAttribute('data-service'); 343 let category = obj.getAttribute('data-category'); 344 let blocked_image_container = obj.parentElement; 345 blocked_image_container.classList.add('cmplz-blocked-content-container'); 346 let curIndex = blocked_image_container.getAttribute('data-placeholder_class_index'); 347 //handle browser native lazy load feature 348 if (obj.getAttribute('loading') === 'lazy' ) { 349 obj.removeAttribute('loading'); 350 obj.setAttribute('data-deferlazy', 1); 351 } 352 353 if ( curIndex == null ) { 354 cmplz_placeholder_class_index++; 355 blocked_image_container.classList.add('cmplz-placeholder-' + cmplz_placeholder_class_index); 356 blocked_image_container.classList.add('cmplz-blocked-content-container'); 357 blocked_image_container.setAttribute('data-placeholder_class_index', cmplz_placeholder_class_index); 358 cmplz_insert_placeholder_text(blocked_image_container, category, service); 359 } 360 }); 361 362 document.querySelectorAll('.cmplz-placeholder-element').forEach(obj => { 363 if ( obj.classList.contains('cmplz-processed') ) { 364 return; 365 } 366 obj.classList.add('cmplz-processed' ); 367 let service = obj.getAttribute('data-service'); 368 let category = obj.getAttribute('data-category'); 369 370 //we set this element as container with placeholder image 371 let blocked_content_container; 372 if ( obj.classList.contains('cmplz-iframe')) { 373 //handle browser native lazy load feature 374 if ( obj.getAttribute('loading') === 'lazy' ) { 375 obj.removeAttribute('loading'); 376 obj.setAttribute('data-deferlazy', 1); 377 } 378 blocked_content_container = obj.parentElement; 379 } else { 380 blocked_content_container = obj; 381 } 382 let curIndex = blocked_content_container.getAttribute('data-placeholder_class_index'); 383 //if the blocked content container class is already added, don't add it again 384 if ( curIndex == null ) { 385 cmplz_placeholder_class_index++; 386 blocked_content_container.classList.add('cmplz-placeholder-' + cmplz_placeholder_class_index); 387 blocked_content_container.classList.add('cmplz-blocked-content-container'); 388 blocked_content_container.setAttribute('data-placeholder_class_index', cmplz_placeholder_class_index); 389 cmplz_insert_placeholder_text(blocked_content_container, category, service); 390 //handle image size for video 391 let src = obj.getAttribute('data-placeholder-image'); 392 if (src && typeof src !== 'undefined' && src.length ) { 393 src = src.replace('url(', '').replace(')', '').replace(/\"/gi, ""); 394 cmplz_append_css('.cmplz-placeholder-' + cmplz_placeholder_class_index + ' {background-image: url(' + src + ') !important;}'); 395 cmplz_set_blocked_content_container_aspect_ratio(obj, src, cmplz_placeholder_class_index); 396 } 397 } 398 }); 399 400 /* 401 * In some cases, like ajax loaded content, the placeholders are initialized again. In that case, the scripts may need to be fired again as well. 402 * In case of an opt-out region and Do Not Track, a consent check will return 'allow', because it doesn't take DNT into account 403 */ 404 405 if ( cmplz_has_consent('statistics') ) { 406 cmplz_enable_category('statistics'); 407 } 408 409 if ( cmplz_has_consent('marketing') ) { 410 cmplz_enable_category('marketing'); 411 } 412 413} 414 415function cmplz_insert_placeholder_text(container, category, service ){ 416 if ( !container.querySelector( ".cmplz-blocked-content-notice" ) ) { 417 let placeholder_text = complianz.placeholdertext; 418 category = category ? category : 'marketing'; 419 let body; 420 if ( typeof placeholder_text !== 'undefined' ) { 421 if ( complianz.clean_cookies == 1 ) { 422 //make service human readable 423 let service_nicename = service ? service.replace('-', ' ') : ''; 424 service_nicename = service_nicename.charAt(0).toUpperCase() + service_nicename.slice(1); 425 placeholder_text = placeholder_text.replace('{service}', service_nicename);
426 body = cmplz_create_element('div', placeholder_text); 427 body.innerHTML = placeholder_text; 428 body.classList.add('cmplz-blocked-content-notice'); 429 let btn = body.querySelector('button'); 430 btn.setAttribute('data-service', service); 431 btn.setAttribute('data-category', category); 432 btn.setAttribute('aria-label', service); 433 let pageLinks = complianz.page_links[complianz.region]; 434 let link = body.querySelector('.cmplz-links a'); 435 if ( pageLinks && pageLinks.hasOwnProperty('cookie-statement') ) { 436 link.setAttribute('href', pageLinks['cookie-statement']['url']); 437 if (link.innerText === '{title}') { 438 link.innerText = pageLinks['cookie-statement']['title']; 439 } 440 } 441 } else { 442 let btn = cmplz_create_element('button', ''); 443 let category_nicename = 'marketing'; 444 if (complianz.categories.hasOwnProperty(category)){ 445 category_nicename = complianz.categories[category]; 446 } 447 448 placeholder_text = placeholder_text.replace('{category}', category_nicename); 449 btn.innerText = placeholder_text; 450 btn.classList.add('cmplz-blocked-content-notice'); 451 btn.classList.add('cmplz-accept-category'); 452 453 //deprecated 454 btn.classList.add('cmplz-accept-'+category); 455 btn.setAttribute('data-service', service ); 456 btn.setAttribute('data-category', category ); 457 btn.setAttribute('aria-label', service ); 458 body=btn; 459 } 460 461 if ( container.tagName!=='VIDEO' ) { 462 container.appendChild(body); 463 } else{ 464 container.parentElement.appendChild(body); 465 } 466 467 } 468 } 469} 470 471/* 472 * Set the height of an image relative to the width, depending on the image widht/height aspect ratio. 473 * 474 * 475 * */ 476 477function cmplz_set_blocked_content_container_aspect_ratio(container, src, placeholder_class_index) { 478 if ( container == null ) return; 479 480 //we set the first parent div as container with placeholder image 481 let blocked_content_container = container.parentElement; 482 483 //handle image size for video 484 let img = new Image(); 485 img.addEventListener("load", function () { 486 let imgWidth = this.naturalWidth; 487 let imgHeight = this.naturalHeight; 488 489 //prevent division by zero. 490 if (imgWidth === 0) imgWidth = 1; 491 let w = blocked_content_container.clientWidth; 492 let h = imgHeight * (w / imgWidth); 493 494 let heightCSS = ''; 495 if (src.indexOf('placeholder.jpg') === -1) { 496 heightCSS = 'height:' + h + 'px;'; 497 } 498 cmplz_append_css('.cmplz-placeholder-' + placeholder_class_index + ' {' + heightCSS + '}'); 499 }); 500 img.src = src; 501} 502/* 503 * Keep window aspect ratio in sync when window resizes 504 * To lower the number of times this code is executed, it is done with a timeout. 505 * 506 * */ 507 508var cmplzResizeTimer; 509window.addEventListener('resize', function(event) { 510 clearTimeout(cmplzResizeTimer); 511 cmplzResizeTimer = setTimeout( cmplz_set_blocked_content_container, 500); 512}, true); 513 514/* 515 * we run this function also on an interval, because with ajax loaded content, the placeholders would otherwise not be handled. 516 */ 517if ( complianz.block_ajax_content == 1 ) { 518 setInterval(function () { 519 cmplz_set_blocked_content_container(); 520 }, 2000); 521} 522 523/* 524 * Check if there are any blocked scripts on the page 525 * @returns {boolean} 526 */ 527function cmplz_has_blocked_scripts(){ 528 let scriptElements = document.querySelectorAll('script[data-category], script[data-service]'); 529 return scriptElements.length>0; 530} 531/* 532 * Enable scripts that were blocked 533 * 534 * */ 535 536function cmplz_enable_category(category, service) { 537 if ( complianz.tm_categories == 1 && category !== '') { 538 cmplz_run_tm_event(category); 539 } 540 541 service = typeof service !== 'undefined' ? service : 'do_not_match'; 542 if ( category === '' ) category = 'do_not_match'; 543 544 if ( category === 'functional' ) { 545 return; 546 } 547 548 //enable cookies for integrations 549 if ( category === 'marketing' ) { 550 cmplz_set_integrations_cookies(); 551 } 552 553 //remove accept cookie notice overlay 554 let selector; 555 if (service !== 'do_not_match') { 556 selector = '.cmplz-blocked-content-notice [data-service='+service+']'; 557 } else { 558 selector = complianz.clean_cookies!=1 ? '.cmplz-blocked-content-notice.cmplz-accept-'+category : '.cmplz-blocked-content-notice [data-category='+category+']'; 559 } 560 document.querySelectorAll(selector).forEach(obj => { 561 let blockedElementService = obj.getAttribute('data-service'); 562 if (obj.parentNode.classList.contains('cmplz-blocked-content-notice')) { 563 obj = obj.parentNode; 564 } 565 //only remove if the service is not explicitly denied 566 if ( !cmplz_is_service_denied(blockedElementService) ) { 567 obj.parentNode.removeChild(obj); 568 } 569 }); 570 571 document.querySelectorAll('[data-category='+category+'], [data-service='+service+']').forEach(obj => { 572 //if a category is activated, but this specific service is denied, skip. 573 let elementService = obj.getAttribute('data-service'); 574 if ( cmplz_is_service_denied(elementService) ) { 575 return; 576 } 577 578 //if native class is included, it isn't blocked, so will have run already 579 if ( obj.getAttribute('data-category') === 'functional' ) { 580 return; 581 } 582 583 if ( obj.classList.contains('cmplz-activated') ) { 584 return; 585 } 586 587 let tagName = obj.tagName; 588 if (tagName==='LINK'){ 589 obj.classList.add('cmplz-activated' ); 590 let src = obj.getAttribute('data-href'); 591 cmplz_load_css( src, category); 592 } else if (tagName ==='IMG'){ 593 obj.classList.add('cmplz-activated' ); 594 let src = obj.getAttribute('data-src-cmplz'); 595 obj.setAttribute('src', src); 596 //handle browser native lazy load feature 597 if ( obj.getAttribute('data-deferlazy') ) { 598 obj.setAttribute('loading', 'lazy'); 599 } 600 cmplz_remove_placeholder(obj); 601 } 602 else if (tagName==='IFRAME'){ 603 obj.classList.add('cmplz-activated' ); 604 let src = obj.getAttribute('data-src-cmplz'); 605 let srcAttribute = obj.getAttribute('data-cmplz-target') ? obj.getAttribute('data-cmplz-target') : 'src'; 606 607 //check if there's an autoplay value we need to pass on, if it's added later on by javascript 608 let autoplay = cmplz_get_url_parameter(obj.getAttribute(srcAttribute), 'autoplay'); 609 if ( autoplay === '1' ) src = src + '&autoplay=1'; 610 //handle browser native lazy load feature 611 if ( obj.getAttribute('data-deferlazy') ) { 612 obj.setAttribute('loading', 'lazy'); 613 } 614 615 obj.addEventListener('load', () => { 616 cmplz_remove_placeholder(obj); 617 }); 618 obj.setAttribute(srcAttribute, src); 619 } else if (obj.classList.contains('cmplz-placeholder-element')) { 620 obj.classList.add('cmplz-activated' ); 621 //other services, no iframe, with placeholders 622 //remove the added classes 623 let cssIndex = obj.getAttribute('data-placeholder_class_index'); 624 obj.classList.remove('cmplz-blocked-content-container'); 625 obj.classList.remove('cmplz-placeholder-' + cssIndex); 626 } 627 628 let details = {}; 629 details.category = category; 630 details.service = service; 631 let event = new CustomEvent('cmplz_category_enabled', { detail: details }); 632 document.dispatchEvent(event); 633 }); 634 635 /* 636 * Let's activate the scripts 637 */ 638 639 //create list of waiting scripts 640 let scriptElements = document.querySelectorAll('script[data-category='+category+'], script[data-service='+service+']');
641 scriptElements.forEach(obj => { 642 let waitfor = obj.getAttribute('data-waitfor'); 643 let src = obj.getAttribute('data-cmplz-src'); 644 if ( waitfor ) { 645 if ( src ) { 646 cmplz_waiting_scripts[waitfor] = src; 647 } else if ( obj.innerText.length > 0 ) { 648 cmplz_waiting_inline_scripts[waitfor] = obj; 649 } 650 } 651 652 //cleanup after adding it to our waiting or scriptElements list. 653 if (obj.parentElement) { 654 obj.parentElement.removeChild(obj); 655 } 656 }); 657 658 //scripts: remove text/plain, and move data-src attribute to src attribute 659 scriptElements.forEach(obj => { 660 //we don't want already activate scripts to fire, but also we don't want scripts that weren't blocked to fire. Hence the check for type 661 let script_mime_type = obj.getAttribute('type'); 662 if ( obj.classList.contains('cmplz-activated') || ( !script_mime_type || script_mime_type==='text/javascript' ) ) { 663 return; 664 } 665 obj.classList.add('cmplz-activated' ); 666 let src = obj.getAttribute('data-cmplz-src'); 667 if ( src ) { 668 obj.removeAttribute('type'); 669 //check if this src or txt is in a waiting script. If so, skip. 670 if ( cmplz_is_waiting_script(cmplz_waiting_scripts, src) ) { 671 return; 672 } 673 674 if ( obj.getAttribute('data-post_scribe_id') ) { 675 let psID = '#' + obj.getAttribute('data-post_scribe_id'); 676 let postScribeObj = document.querySelector(psID); 677 if ( postScribeObj ) { 678 postScribeObj.innerHtml(''); 679 postscribe(psID, '<script src=' + src + '></script>'); 680 } 681 } else { 682 cmplz_run_script(src, category, 'src', obj ); 683 } 684 685 } else if (obj.innerText.length > 0 ) { 686 //check if this src or txt is in a waiting script. If so, skip. 687 if (cmplz_is_waiting_script(cmplz_waiting_inline_scripts, obj.innerText )) { 688 return; 689 } 690 691 cmplz_run_script( obj.innerText, category, 'inline', obj ); 692 } 693 }); 694 695 //fire an event so custom scripts can hook into this. 696 let details = {}; 697 details.category = category; 698 details.service = service; 699 details.categories = cmplz_accepted_categories(); 700 details.services = cmplz_get_all_service_consents(); 701 details.region = complianz.region; 702 let event = new CustomEvent('cmplz_enable_category', { detail: details }); 703 document.dispatchEvent(event); 704 //if there are no blockable scripts at all, we still want to provide a hook 705 //in most cases, there are blocked scripts, and this code won't run yet. In that 706 //case it's run from the script activation callbacks. 707 if ( !cmplz_has_blocked_scripts() ) { 708 cmplz_run_after_all_scripts(category); 709 } 710} 711 712/* 713 * remove added classes from the blocked content container 714 * 715 * @param obj 716 */ 717function cmplz_remove_placeholder(obj){ 718 //we get the closest, not the parent, because a script could have inserted a div in the meantime. 719 let blocked_content_container = obj.closest('.cmplz-blocked-content-container'); 720 if (blocked_content_container) { 721 let cssIndex = blocked_content_container.getAttribute('data-placeholder_class_index'); 722 blocked_content_container.classList.remove('cmplz-blocked-content-container'); 723 blocked_content_container.classList.remove('cmplz-placeholder-' + cssIndex); 724 } 725 obj.classList.remove('cmplz-iframe-styles'); 726 obj.classList.remove('cmplz-iframe'); 727 obj.classList.remove('video-wrap'); 728} 729 730/* 731 * check if the passed source has a waiting script that should be executed, and return it if so. 732 * @param waiting_scripts 733 * @param src 734 * @returns {*} 735 */ 736 737function cmplz_get_waiting_script( waiting_scripts, src ) { 738 for ( let waitfor in waiting_scripts ) { 739 if ( waiting_scripts.hasOwnProperty(waitfor)) { 740 if ( src.indexOf(waitfor) !== -1 ) { 741 let output = waiting_scripts[waitfor]; 742 delete waiting_scripts[waitfor]; 743 return output; 744 } 745 } 746 } 747 748 return false; 749} 750 751/* 752 * Because we need a key=>value array in javascript, the .length check for an empty array doesn't work. 753 * @param arr 754 * @returns {boolean} 755 */ 756function cmplz_array_is_empty(arr) { 757 for (let key in arr) { 758 if (arr.hasOwnProperty(key)) { 759 return false; 760 } 761 } 762 763 return true; 764} 765 766/* 767 * Check if the passed src or script is waiting for another script and should not execute 768 * @param waiting_scripts 769 * @param srcOrScript 770 */ 771
772function cmplz_is_waiting_script(waiting_scripts, srcOrScript) { 773 for (let waitfor in waiting_scripts) { 774 if ( waiting_scripts.hasOwnProperty(waitfor) ) { 775 let waitingScript = waiting_scripts[waitfor]; 776 if (typeof waitingScript !== 'string') waitingScript = waitingScript.innerText; 777 778 if (srcOrScript.indexOf(waitingScript) !== -1 || waitingScript.indexOf(srcOrScript) !== -1) { 779 return true; 780 } 781 } 782 } 783 return false; 784} 785 786/* 787 * if all scripts have been executed, fire a hook. 788 */ 789 790function cmplz_run_after_all_scripts(category) { 791 if (!cmplz_all_scripts_hook_fired && cmplz_array_is_empty(cmplz_waiting_inline_scripts) && cmplz_array_is_empty(cmplz_waiting_scripts) ) { 792 let event = new CustomEvent('cmplz_run_after_all_scripts', { detail: category }); 793 document.dispatchEvent(event); 794 cmplz_all_scripts_hook_fired = true; 795 } 796} 797 798/* 799 * Fire an event in Tag Manager 800 * 801 * 802 * */ 803 804let cmplz_fired_events = []; 805function cmplz_run_tm_event(category) { 806 if (cmplz_fired_events.indexOf(category) === -1) { 807 cmplz_fired_events.push(category); 808 window.dataLayer = window.dataLayer || []; 809 window.dataLayer.push({ 810 'event': complianz.prefix+'event_'+category 811 }); 812 let event = new CustomEvent('cmplz_tag_manager_event', { detail: category }); 813 document.dispatchEvent(event); 814 } 815} 816 817/* 818 * Function to handle backward compatibility 819 * 820 */ 821 822function cmplz_legacy(){ 823 let has_recaptcha = false; 824 document.querySelectorAll('[data-service=recaptcha]').forEach(obj => { 825 obj.setAttribute('data-service', 'google-recaptcha'); 826 has_recaptcha=true; 827 }); 828 829 if ( has_recaptcha ) { 830 console.log('recaptcha as service name is deprecated. Please rename the service in your custom html to google-recaptcha'); 831 document.body.classList.add( 'cmplz-google-recaptcha' ); 832 } 833} 834 835window.conditionally_show_banner = function() { 836 //merge userdata with complianz data, in case a b testing is used with user specific cookie banner data 837 //objects are merged so user_data will override data in complianz object 838 complianz = cmplz_merge_object( complianz, cmplz_user_data ); 839 //check if we need to redirect to another legal document, for a specific region 840 cmplz_maybe_auto_redirect(); 841 cmplz_set_blocked_content_container(); 842 cmplz_legacy(); 843 844 /* 845 * Integration with WordPress, tell what kind of consent type we're using, then fire an event 846 */ 847 848 window.wp_consent_type = complianz.consenttype; 849 let event = new CustomEvent('wp_consent_type_defined'); 850 document.dispatchEvent( event ); 851 event = new CustomEvent('cmplz_before_cookiebanner' ); 852 document.dispatchEvent(event); 853 if ( complianz.forceEnableStats == 1 && complianz.consenttype === 'optin' ) { 854 cmplz_set_consent('statistics', 'allow'); 855 } 856 857 let rev_cats = cmplz_categories.reverse(); 858 for (let key in rev_cats) { 859 if ( rev_cats.hasOwnProperty(key) ) { 860 let category = cmplz_categories[key]; 861 if ( cmplz_has_consent(category) ) { 862 cmplz_enable_category(category); 863 } 864 } 865 } 866 if ( cmplz_exists_service_consent() ) { 867 //if any service is enabled, allow the general services also, because some services are partially 'general' 868 cmplz_enable_category('', 'general'); 869 let services = cmplz_get_services_on_page(); 870 for (let key in services) { 871 if ( services.hasOwnProperty(key) ) { 872 let service = services[key].service; 873 let category = services[key].category; 874 if ( cmplz_has_service_consent( service, category )) { 875 document.querySelectorAll('.cmplz-accept-service[data-service=' + service + ']').forEach(obj => { 876 obj.checked = true; 877 }); 878 cmplz_enable_category('', service); 879 } 880 } 881 } 882 } 883 884 cmplz_sync_category_checkboxes(); 885 cmplz_integrations_init(); 886 cmplz_check_cookie_policy_id(); 887 cmplz_set_up_auto_dismiss(); 888 889 //if we're on the cookie policy page, we dynamically load the applicable revoke checkbox 890 cmplz_load_manage_consent_container(); 891 892 event = new CustomEvent('cmplz_cookie_banner_data', { detail: complianz }); 893 document.dispatchEvent(event); 894 895 //if no categories were saved before, we do it now 896 if ( cmplz_get_cookie('saved_categories') === '' ) { 897 //for Non optin/optout visitors, and DNT users, we just track the no-warning option 898 if ( complianz.consenttype !== 'optin' && complianz.consenttype !== 'optout' ) { 899 cmplz_track_status( 'no_warning' ); 900 } else if ( cmplz_do_not_track() ) { 901 cmplz_track_status('do_not_track' ); 902 } 903 } 904 905 cmplz_set_category_as_body_class(); 906 //fire cats event, but do not fire a track, as we do this on exit. 907 cmplz_fire_categories_event(); 908 if ( !cmplz_do_not_track() ) { 909 if (complianz.consenttype === 'optin') { 910 if (complianz.forceEnableStats) { 911 cmplz_enable_category('statistics'); 912 } 913 console.log('opt-in'); 914 show_cookie_banner(); 915 } else if (complianz.consenttype === 'optout') { 916 console.log('opt-out'); 917 show_cookie_banner(); 918 } else {
919 console.log('other consent type, no cookie warning'); 920 //on other consent types, all scripts are enabled by default. 921 cmplz_accept_all(); 922 // cmplz_fire_categories_event(); 923 } 924 } else { 925 console.log('global privacy control or do not track detected: no banner.'); 926 cmplz_track_status( 'do_not_track' ); 927 } 928} 929 930/** 931 * Check if User has set either GPC or DNT in the browser. 932 * @returns {boolean} 933 */ 934function cmplz_do_not_track(){ 935 let dnt = 'doNotTrack' in navigator && navigator.doNotTrack === '1'; 936 let gpc = 'globalPrivacyControl' in navigator && navigator.globalPrivacyControl; 937 return !!(complianz.do_not_track_enabled && (gpc || dnt)); 938} 939 940/* 941 * Get list of services active on the page 942 * @returns {*[]} 943 */ 944function cmplz_get_services_on_page(){ 945 let services=[]; 946 document.querySelectorAll('[data-service]').forEach(obj => { 947 let service = obj.getAttribute('data-service'); 948 let category = obj.getAttribute('data-category'); 949 if ( services.indexOf(service)==-1 ) { 950 services.push({ 951 'category': category, 952 'service':service, 953 }); 954 } 955 }); 956 return services; 957} 958 959/* 960 * Run the actual cookie warning 961 * 962 * */ 963 964window.show_cookie_banner = function () { 965 let disableCookiebanner = complianz.disable_cookiebanner || cmplz_is_speedbot(); 966 //do not show banner when manage consent area on cookie policy is visible 967 //when users use only the shortcode, the manage consent container is not active, but the dropdown cookie policy class is. 968 //when the complianz shortcode is used, the dropdown cookie policy class is loaded late because it's loaded with javascript. 969 let tmpDismissCookiebanner = false; 970 if ( document.querySelector('#cmplz-manage-consent-container') || document.querySelector('.cmplz-dropdown-cookiepolicy') ) { 971 tmpDismissCookiebanner = true; 972 } 973 974 var fragment = document.createDocumentFragment(); 975 let container = document.getElementById('cmplz-cookiebanner-container'); 976 if (container) { 977 fragment.appendChild(container); 978 document.body.prepend(fragment); 979 } 980 981 let link = document.createElement("link"); 982 let pageLinks = complianz.page_links[complianz.region]; 983 //get correct banner, based on banner_id 984 cmplz_banner = document.querySelector('.cmplz-cookiebanner.banner-'+complianz.user_banner_id+'.'+complianz.consenttype); 985 if ( !cmplz_banner ) { 986 disableCookiebanner = true; 987 } 988 cmplz_manage_consent_button = document.querySelector('#cmplz-manage-consent .cmplz-manage-consent.manage-consent-'+complianz.user_banner_id); 989 let css_file_url = complianz.css_file.replace('{type}', complianz.consenttype ).replace('{banner_id}', complianz.user_banner_id); 990 if ( complianz.css_file.indexOf('cookiebanner/css/defaults/banner') != -1 ) { 991 console.log('Fallback default css file used. Please re-save banner settings, or check file writing permissions in uploads directory'); 992 } 993 994 link.href = css_file_url; 995 link.type = "text/css"; 996 link.rel = "stylesheet"; 997 link.onload = function () { 998 if ( !disableCookiebanner ) { 999 cmplz_banner.classList.remove('cmplz-hidden'); 1000 cmplz_manage_consent_button.classList.remove('cmplz-hidden'); 1001 } 1002 } 1003 document.getElementsByTagName("head")[0].appendChild(link); 1004 if ( cmplz_banner && !disableCookiebanner ) { 1005 cmplz_banner.querySelectorAll('.cmplz-links a:not(.cmplz-external), .cmplz-buttons a:not(.cmplz-external)').forEach(obj => { 1006 let docElement = obj; 1007 docElement.classList.add('cmplz-hidden'); 1008 for (let pageType in pageLinks ) { 1009 if (pageLinks.hasOwnProperty(pageType) && docElement.classList.contains(pageType)) { 1010 docElement.setAttribute('href', pageLinks[pageType]['url'] + docElement.getAttribute('data-relative_url')); 1011 if ( docElement.innerText === '{title}') { 1012 docElement.innerText = cmplz_html_decode(pageLinks[pageType]['title']); 1013 } 1014 docElement.classList.remove('cmplz-hidden'); 1015 } 1016 } 1017 }); 1018 1019 cmplz_set_banner_status(); 1020 //we don't use the setBannerStatus function here, as we don't want to save it in a cookie now. 1021 if ( tmpDismissCookiebanner ) { 1022 cmplz_banner.classList.remove('cmplz-show'); 1023 cmplz_banner.classList.add('cmplz-dismissed'); 1024 cmplz_manage_consent_button.classList.remove('cmplz-dismissed'); 1025 cmplz_manage_consent_button.classList.add('cmplz-show'); 1026 } 1027 } 1028 1029 let event = new CustomEvent('cmplz_cookie_warning_loaded', {detail: complianz.region}); 1030 document.dispatchEvent(event); 1031} 1032/* 1033 * Get the status of the banner: dismissed | show 1034 * @returns {string} 1035 */ 1036window.cmplz_get_banner_status = function (){ 1037 return cmplz_get_cookie('banner-status'); 1038} 1039 1040/* 1041 * Set the banner status so it will be either shown or dismissed, and store it in a cookie. 1042 * @param status (optional) 1043 */ 1044 1045window.cmplz_set_banner_status = function ( status ){ 1046 let prevStatus = cmplz_get_cookie('banner-status'); 1047 status = typeof status !== 'undefined' ? status : prevStatus; 1048 if ( status !== prevStatus ) { 1049 cmplz_set_cookie( 'banner-status', status ); 1050 } 1051 if (status.length===0){ 1052 status = 'show'; 1053 } 1054 1055 if (status==='show') { 1056 prevStatus = 'dismissed'; 1057 } else { 1058 prevStatus = 'show'; 1059 } 1060 1061 if ( cmplz_banner && status.length>0 ) { 1062 cmplz_banner.classList.remove('cmplz-'+prevStatus); 1063 cmplz_banner.classList.add('cmplz-'+status ); 1064 if ( cmplz_manage_consent_button ) { 1065 cmplz_manage_consent_button.classList.add('cmplz-'+prevStatus); 1066 cmplz_manage_consent_button.classList.remove('cmplz-'+status); 1067 } 1068 } 1069 1070 if ( cmplz_banner_container && complianz.soft_cookiewall ) { 1071 cmplz_banner_container.classList.remove('cmplz-'+prevStatus); 1072 cmplz_banner_container.classList.add('cmplz-'+status );
1073 cmplz_banner_container.classList.add('cmplz-soft-cookiewall'); 1074 } 1075 let event = new CustomEvent('cmplz_banner_status', { detail: status }); 1076 document.dispatchEvent(event); 1077 cmplz_start_clean(); 1078} 1079 1080/* 1081 * Check if current visitor is a bot 1082 * 1083 * @returns {boolean} 1084 */ 1085function cmplz_is_bot(){ 1086 var botPattern = "(googlebot\/|Googlebot-Mobile|Googlebot-Image|Google favicon|Mediapartners-Google|bingbot|slurp|java|wget|curl|Commons-HttpClient|Python-urllib|libwww|httpunit|nutch|phpcrawl|msnbot|jyxobot|FAST-WebCrawler|FAST Enterprise Crawler|biglotron|teoma|convera|seekbot|gigablast|exabot|ngbot|ia_archiver|GingerCrawler|webmon |httrack|webcrawler|grub.org|UsineNouvelleCrawler|antibot|netresearchserver|speedy|fluffy|bibnum.bnf|findlink|msrbot|panscient|yacybot|AISearchBot|IOI|ips-agent|tagoobot|MJ12bot|dotbot|woriobot|yanga|buzzbot|mlbot|yandexbot|purebot|Linguee Bot|Voyager|CyberPatrol|voilabot|baiduspider|citeseerxbot|spbot|twengabot|postrank|turnitinbot|scribdbot|page2rss|sitebot|linkdex|Adidxbot|blekkobot|ezooms|dotbot|Mail.RU_Bot|discobot|heritrix|findthatfile|europarchive.org|NerdByNature.Bot|sistrix crawler|ahrefsbot|Aboundex|domaincrawler|wbsearchbot|summify|ccbot|edisterbot|seznambot|ec2linkfinder|gslfbot|aihitbot|intelium_bot|facebookexternalhit|yeti|RetrevoPageAnalyzer|lb-spider|sogou|lssbot|careerbot|wotbox|wocbot|ichiro|DuckDuckBot|lssrocketcrawler|drupact|webcompanycrawler|acoonbot|openindexspider|gnam gnam spider|web-archive-net.com.bot|backlinkcrawler|coccoc|integromedb|content crawler spider|toplistbot|seokicks-robot|it2media-domain-crawler|ip-web-crawler.com|siteexplorer.info|elisabot|proximic|changedetection|blexbot|arabot|WeSEE:Search|niki-bot|CrystalSemanticsBot|rogerbot|360Spider|psbot|InterfaxScanBot|Lipperhey SEO Service|CC Metadata Scaper|g00g1e.net|GrapeshotCrawler|urlappendbot|brainobot|fr-crawler|binlar|SimpleCrawler|Livelapbot|Twitterbot|cXensebot|smtbot|bnf.fr_bot|A6-Indexer|ADmantX|Facebot|Twitterbot|OrangeBot|memorybot|AdvBot|MegaIndex|SemanticScholarBot|ltx71|nerdybot|xovibot|BUbiNG|Qwantify|archive.org_bot|Applebot|TweetmemeBot|crawler4j|findxbot|SemrushBot|yoozBot|lipperhey|y!j-asr|Domain Re-Animator Bot|AddThis)"; 1087 var reBot = new RegExp(botPattern, 'i'); 1088 var userAgent = navigator.userAgent; 1089 return reBot.test(userAgent); 1090} 1091/* 1092 * Check if current visitor is a speedbot 1093 * 1094 * @returns {boolean} 1095 */ 1096function cmplz_is_speedbot(){ 1097 var userAgent = navigator.userAgent; 1098 var speedBotPattern = "(GTmetrix|pingdom|pingbot|Lighthouse)"; 1099 var speedBot = new RegExp(speedBotPattern, 'i'); 1100 return speedBot.test(userAgent); 1101} 1102 1103/* 1104 * Check if there is consent for a category or service 1105 * @param category 1106 * @returns {boolean} 1107 */ 1108window.cmplz_has_consent = function ( category ){ 1109 if ( cmplz_is_bot() ) { 1110 return true; 1111 } 1112 1113 if ( category === 'functional' ) { 1114 return true; 1115 } 1116 1117 let has_consent, value; 1118 1119 /* 1120 * categories 1121 */ 1122 value = cmplz_get_cookie(category); 1123 if ( (complianz.consenttype === 'optout' || complianz.consenttype === 'other') && value === '') { 1124 //if it's opt out and no cookie is set we should return true 1125 has_consent = true; 1126 } else { 1127 //all other situations, return only true if value is allow 1128 has_consent = (value === 'allow'); 1129 } 1130 1131 return has_consent; 1132} 1133 1134/* 1135 * Check if a service has consent 1136 * @param service 1137 * @returns {boolean|*} 1138 */ 1139window.cmplz_is_service_denied = function ( service ) { 1140 //Check if it's in the consented services cookie 1141 var consented_services_json = cmplz_get_cookie('consented_services'); 1142 var consented_services; 1143 try { 1144 consented_services = JSON.parse(consented_services_json); 1145 } catch (e) { 1146 consented_services = {}; 1147 } 1148 1149 if ( !consented_services.hasOwnProperty( service ) ){ 1150 return false; 1151 } else { 1152 return !consented_services[service]; 1153 } 1154} 1155 1156/* 1157 * Check if a service has consent 1158 * @param service 1159 * @param category 1160 * @returns {boolean|*} 1161 */ 1162window.cmplz_has_service_consent = function ( service, category ) { 1163 //Check if it's in the consented services cookie 1164 var consented_services_json = cmplz_get_cookie('consented_services'); 1165 var consented_services; 1166 try { 1167 consented_services = JSON.parse(consented_services_json); 1168 } catch (e) { 1169 consented_services = {}; 1170 } 1171 1172 if ( !consented_services.hasOwnProperty( service ) ){ 1173 //default to the category 1174 return cmplz_has_consent( category ); 1175 } else { 1176 return consented_services[service]; 1177 } 1178} 1179 1180/* 1181 * check if there's at least one service with consent 1182 * @returns {boolean} 1183 */ 1184function cmplz_exists_service_consent(){ 1185 var consented_services_json = cmplz_get_cookie('consented_services'); 1186 var consented_services; 1187 try { 1188 consented_services = JSON.parse(consented_services_json); 1189 for (const key in consented_services) { 1190 if ( consented_services.hasOwnProperty(key) ) { 1191 if (consented_services[key] == true) { 1192 return true; 1193 } 1194 } 1195 } 1196 } catch (e) { 1197 return false;
1198 } 1199 return false; 1200} 1201 1202/* 1203 * Set consent for a service 1204 * @param service 1205 * @param consented 1206 */ 1207function cmplz_set_service_consent( service, consented ){ 1208 var consented_services_json = cmplz_get_cookie('consented_services'); 1209 var consented_services; 1210 try { 1211 consented_services = JSON.parse(consented_services_json); 1212 } catch (e) { 1213 consented_services = {}; 1214 } 1215 consented_services[service] = consented; 1216 cmplz_set_cookie('consented_services', JSON.stringify(consented_services) ); 1217 let details = {}; 1218 details.service = service; 1219 details.value = consented; 1220 details.region = complianz.region; 1221 //when the status is changed, we may need to fire scripts again, so we reset it. 1222 cmplz_all_scripts_hook_fired = false; 1223 let event = new CustomEvent('cmplz_status_change_service', { detail: details }); 1224 document.dispatchEvent(event); 1225} 1226 1227/* 1228 * Remove all service consents 1229 */ 1230function cmplz_clear_all_service_consents(){ 1231 cmplz_set_cookie('consented_services', ''); 1232} 1233 1234/* 1235 * Get all consented or denied services 1236 */ 1237 1238function cmplz_get_all_service_consents(){ 1239 var consented_services_json = cmplz_get_cookie('consented_services'); 1240 var consented_services; 1241 try { 1242 consented_services = JSON.parse(consented_services_json); 1243 } catch (e) { 1244 consented_services = {}; 1245 } 1246 return consented_services; 1247} 1248/* 1249 * Get cookie path 1250 * @returns {*} 1251 */ 1252function cmplz_get_cookie_path(){ 1253 return typeof complianz.cookie_path !== 'undefined' && complianz.cookie_path !== '' ? complianz.cookie_path : '/'; 1254} 1255 1256/* 1257 * retrieve domain to set the cookies on 1258 * @returns {string} 1259 */ 1260function cmplz_get_cookie_domain(){ 1261 var domain = ''; 1262 if ( complianz.set_cookies_on_root == 1 && complianz.cookie_domain.length>3){ 1263 domain = complianz.cookie_domain; 1264 } 1265 if (domain.indexOf('localhost') !== -1 ) { 1266 domain = ''; 1267 } 1268 return domain; 1269} 1270 1271/* 1272 * Set consent for a category 1273 * @param category 1274 * @param value 1275 */ 1276window.cmplz_set_consent = function (category, value){ 1277 cmplz_set_accepted_cookie_policy_id(); 1278 //functional is always allow 1279 value = category==='functional' ? 'allow' : value; 1280 let previous_value = cmplz_get_cookie(category); 1281 1282 //keep checkboxes in banner and on cookie policy in sync 1283 //do this before the change check to ensure sync: https://github.com/Really-Simple-Plugins/complianz-gdpr/issues/324 1284 let checked = value === 'allow'; 1285 document.querySelectorAll('input.cmplz-'+category).forEach(obj => { 1286 obj.checked = checked; 1287 }); 1288 1289 //do not trigger a change event if nothing has changed. 1290 if ( previous_value === value ) { 1291 return; 1292 } 1293 1294 cmplz_set_cookie(category, value); 1295 if ( value === 'allow' ) { 1296 cmplz_enable_category(category); 1297 } 1298 1299 cmplz_wp_set_consent(category, value); 1300 if ( category === 'statistics' ) { 1301 cmplz_wp_set_consent('statistics-anonymous', 'allow'); 1302 } 1303 1304 let details = new Object(); 1305 details.category = category; 1306 details.value = value; 1307 details.region = complianz.region; 1308 details.categories = cmplz_accepted_categories(); 1309 //when the status is changed, we may need to fire scripts again, so we reset it. 1310 cmplz_all_scripts_hook_fired = false; 1311 let event = new CustomEvent('cmplz_status_change', { detail: details }); 1312 document.dispatchEvent(event); 1313 if ( category === 'marketing' && value === 'deny' && previous_value === 'allow' ) { 1314 cmplz_integrations_revoke(); 1315 //give the code some time to finish, so our track status code can send a signal to the backend. 1316 setTimeout(function(){ 1317 cmplz_reload_browser_compatible() 1318 }, 500); 1319 } 1320} 1321 1322/* 1323* In some browsers, like firefox, the reload does not force reload, but keeps cached data, causing e.g. Google Maps to load anyway. 1324*/ 1325function cmplz_reload_browser_compatible(){ 1326 if( navigator.userAgent.toLowerCase().indexOf('firefox') > -1 ){ 1327 const url = new URL(window.location.href); 1328 url.searchParams.set('cmplz-force-reload', Date.now().toString()); 1329 window.location.href = url.toString(); 1330 } else { 1331 window.location.reload(); 1332 } 1333} 1334 1335/* 1336 * We use ajax to check the consenttype based on region, otherwise caching could prevent the user specific warning 1337 * 1338 * */ 1339 1340var cmplz_user_data = []; 1341//check if it's already stored 1342if (typeof (Storage) !== "undefined" && sessionStorage.cmplz_user_data) { 1343 cmplz_user_data = JSON.parse(sessionStorage.cmplz_user_data); 1344} 1345 1346//if not stored yet, load. As features in the user object can be changed on updates, we also check for the version 1347if ( complianz.geoip == 1 && (cmplz_user_data.length == 0 || (cmplz_user_data.version !== complianz.version) || (cmplz_user_data.banner_version !== complianz.banner_version)) ) { 1348 1349 var request = new XMLHttpRequest(); 1350 let cmplzUserRegion = cmplz_get_url_parameter(window.location.href, 'cmplz_user_region'); 1351 cmplzUserRegion = cmplzUserRegion ? '&cmplz_user_region=' + cmplzUserRegion : ''; 1352 request.open('GET', complianz.url+'banner?'+complianz.locale+cmplzUserRegion, true); 1353 request.setRequestHeader('Content-type', 'application/json'); 1354 request.send(); 1355 request.onload = function() { 1356 cmplz_user_data = JSON.parse(request.response); 1357 sessionStorage.cmplz_user_data = JSON.stringify(cmplz_user_data); 1358 conditionally_show_banner(); 1359 }; 1360} else { 1361 conditionally_show_banner(); 1362} 1363 1364/* 1365 * when ab testing, or using records of consent, we want to keep track of the unique user id 1366 */ 1367 1368if ( complianz.store_consent == 1 ) { 1369 var cmplz_id_cookie = cmplz_get_cookie('id'); 1370 var cmplz_id_session = ''; 1371 var cmplz_id = ''; 1372 if (typeof (Storage) !== "undefined" && sessionStorage.cmplz_id) { 1373 cmplz_id_session = JSON.parse(sessionStorage.cmplz_id); 1374 } 1375 1376 if ( cmplz_id_cookie.length == 0 && cmplz_id_session.length > 0 ) { 1377 cmplz_id = cmplz_id_session; 1378 cmplz_set_cookie('id', cmplz_id ); 1379 } 1380 1381 if ( cmplz_id_cookie.length > 0 && cmplz_id_session.length == 0 ) { 1382 cmplz_id = cmplz_id_cookie; 1383 } 1384 1385 if ( typeof (Storage) !== "undefined" ) { 1386 sessionStorage.cmplz_id = JSON.stringify(cmplz_id); 1387 } 1388} 1389 1390// visibilitychange and pagehide work in more browsers hence we check if they are supported and try to use them 1391document.addEventListener('visibilitychange', function () { 1392 if ( document.visibilityState === 'hidden' ) { 1393 cmplz_track_status_end(); 1394 } 1395}); 1396window.addEventListener("pagehide", cmplz_track_status_end, false ); 1397window.addEventListener("beforeunload", cmplz_track_status_end, false ); 1398 1399function cmplz_track_status_end(){ 1400 if ( !cmplz_consent_stored_once ) { 1401 cmplz_track_status(); 1402 } 1403} 1404 1405/* 1406 * This creates an API which devs can use to trigger actions in complianz. 1407 */ 1408document.addEventListener('cmplz_consent_action', function (e) { 1409 cmplz_set_consent( e.detail.category , 'allow' ); 1410 cmplz_fire_categories_event(); 1411 cmplz_track_status(); 1412}); 1413 1414/* 1415 * Accept all categories 1416 */ 1417window.cmplz_accept_all = function(){ 1418 cmplz_clear_all_service_consents(); 1419 for (var key in cmplz_categories) { 1420 if ( cmplz_categories.hasOwnProperty(key) ) { 1421 cmplz_set_consent(cmplz_categories[key], 'allow'); 1422 } 1423 } 1424 cmplz_sync_category_checkboxes(); 1425} 1426 1427/* 1428 * Deny all categories, and reload if needed. 1429 */ 1430window.cmplz_deny_all = function(){ 1431 for (var key in cmplz_categories) { 1432 if ( cmplz_categories.hasOwnProperty(key) ) { 1433 cmplz_set_consent(cmplz_categories[key], 'deny'); 1434 } 1435 } 1436 var consentLevel = cmplz_highest_accepted_category(); 1437 var reload = false;
1438 1439 if (consentLevel !== 'functional' || cmplz_exists_service_consent() ) { 1440 reload = true; 1441 } 1442 if ( cmplz_clear_cookies('cmplz_service') ) { 1443 reload = true; 1444 } 1445 1446 //has to be after the check if should be reloaded, otherwise that check won't work. 1447 cmplz_clear_all_service_consents(); 1448 cmplz_integrations_revoke(); 1449 cmplz_fire_categories_event(); 1450 cmplz_track_status(); 1451 1452 let event = new CustomEvent('cmplz_revoke', { detail: reload }); 1453 document.dispatchEvent(event); 1454 1455 //we need to let the iab extension handle the reload, otherwise the consent revoke might not be ready yet. 1456 if ( !complianz.tcf_active && reload ) { 1457 cmplz_reload_browser_compatible(); 1458 } 1459} 1460 1461/* 1462 * For both opt-in and opt-out, clicking cmplz-accept should result in accepting all categories 1463 */ 1464cmplz_add_event('click', '.cmplz-accept', function(e){ 1465 e.preventDefault(); 1466 cmplz_accept_all(); 1467 cmplz_set_banner_status('dismissed'); 1468 cmplz_fire_categories_event(); 1469 cmplz_track_status(); 1470}); 1471 1472/* 1473 * Accept marketing cookies by clicking any other link cookie acceptance from a custom link 1474 */ 1475 1476//cmplz-accept-marketing is deprecated 1477cmplz_add_event('click', '.cmplz-accept-category, .cmplz-accept-marketing', function(e){ 1478 e.preventDefault(); 1479 let obj = e.target; 1480 var service = obj.getAttribute('data-service'); 1481 var category = obj.getAttribute('data-category'); 1482 category = category ? category : 'marketing'; 1483 if ( complianz.clean_cookies == 1 && typeof service !== 'undefined' && service ){ 1484 cmplz_set_service_consent(service, true); 1485 cmplz_enable_category('', 'general'); 1486 cmplz_enable_category('', service); 1487 } else { 1488 //we're activating a category, so do not need service activation here. 1489 // cmplz_enable_category('', 'general'); 1490 cmplz_set_consent( category, 'allow' ); 1491 } 1492 cmplz_set_banner_status('dismissed'); 1493 cmplz_fire_categories_event(); 1494 cmplz_track_status(); 1495}); 1496 1497/* 1498 * Accept a specific service 1499 */ 1500cmplz_add_event('click', '.cmplz-accept-service', function(e){ 1501 let obj = e.target; 1502 //INPUT should be handled by change event, these are checkboxes on the cookie policy 1503 let tagName = obj.tagName; 1504 if ( tagName === 'INPUT' ) { 1505 return; 1506 } 1507 let service = obj.getAttribute('data-service'); 1508 if ( typeof service !== 'undefined' ){ 1509 cmplz_set_service_consent(service, true); 1510 cmplz_enable_category('', 'general'); 1511 cmplz_enable_category('', service); 1512 } 1513 cmplz_fire_categories_event(); 1514 cmplz_track_status(); 1515}); 1516/* 1517 * Accept a specific service 1518 */ 1519cmplz_add_event('change', '.cmplz-accept-service', function(e){ 1520 let obj = e.target; 1521 let tagName = obj.tagName; 1522 let service = obj.getAttribute('data-service'); 1523 if ( typeof service !== 'undefined' ) { 1524 //inputs are from the consent per service option on the cookie policy. 1525 if ( tagName === 'INPUT' ) { 1526 cmplz_set_banner_status('dismissed'); 1527 if ( obj.checked ){ 1528 cmplz_set_service_consent(service, true); 1529 cmplz_enable_category('', service); 1530 } else { 1531 cmplz_set_service_consent(service, false); 1532 //give our track status time to finish 1533 setTimeout(function(){ 1534 cmplz_reload_browser_compatible() 1535 }, 500); 1536 } 1537 //if not input, it's a placeholder 1538 } else { 1539 e.preventDefault(); 1540 cmplz_set_service_consent(service, true); 1541 cmplz_enable_category('', 'general'); 1542 cmplz_enable_category('', service); 1543 1544 //give our track status time to finish 1545 setTimeout(function(){ 1546 cmplz_reload_browser_compatible() 1547 }, 500); 1548 } 1549 } 1550 cmplz_fire_categories_event(); 1551 cmplz_track_status(); 1552}); 1553 1554 1555 1556/* 1557 * On the banner, clicking a category should fire the category only after the save button is clicked. 1558 * 1559 */ 1560cmplz_add_event('click', '.cmplz-save-preferences', function(e){ 1561 let obj = e.target; 1562 cmplz_banner = obj.closest('.cmplz-cookiebanner'); 1563 for (var key in cmplz_categories) { 1564 if ( cmplz_categories.hasOwnProperty(key) ) { 1565 var category = cmplz_categories[key]; 1566 var categoryElement = cmplz_banner.querySelector('input.cmplz-' + category); 1567 if (categoryElement) { 1568 if (categoryElement.checked) { 1569 cmplz_set_consent(category, 'allow'); 1570 } else { 1571 cmplz_set_consent(category, 'deny'); 1572 } 1573 } 1574 } 1575 } 1576 cmplz_set_banner_status('dismissed'); 1577 cmplz_fire_categories_event(); 1578 cmplz_track_status(); 1579}); 1580 1581cmplz_add_event('click', '.cmplz-close', function(e){ 1582 cmplz_set_banner_status('dismissed'); 1583}); 1584 1585cmplz_add_event('click', '.cmplz-view-preferences', function(e){ 1586 let obj = e.target; 1587 cmplz_banner = obj.closest('.cmplz-cookiebanner'); 1588 if ( cmplz_banner.querySelector('.cmplz-categories').classList.contains('cmplz-fade-in')) {
1589 cmplz_banner.classList.remove('cmplz-categories-visible'); 1590 cmplz_banner.querySelector('.cmplz-categories' ).classList.remove('cmplz-fade-in'); 1591 cmplz_banner.querySelector('.cmplz-view-preferences' ).style.display = 'block'; 1592 cmplz_banner.querySelector('.cmplz-save-preferences' ).style.display = 'none'; 1593 } else { 1594 cmplz_banner.classList.add('cmplz-categories-visible'); 1595 cmplz_banner.querySelector('.cmplz-categories' ).classList.add('cmplz-fade-in'); 1596 cmplz_banner.querySelector('.cmplz-view-preferences' ).style.display = 'none'; 1597 cmplz_banner.querySelector('.cmplz-save-preferences' ).style.display = 'block'; 1598 } 1599}); 1600/* 1601 * On the cookie policy, clicking a category should fire the category immediately 1602 * 1603 */ 1604cmplz_add_event('change', '.cmplz-manage-consent-container .cmplz-category', function(e){ 1605 for (var key in cmplz_categories) { 1606 if ( cmplz_categories.hasOwnProperty(key) ) { 1607 var category = cmplz_categories[key]; 1608 var categoryElement = document.querySelector('.cmplz-manage-consent-container input.cmplz-' + category); 1609 if (categoryElement) { 1610 if (categoryElement.checked) { 1611 cmplz_set_consent(category, 'allow'); 1612 } else { 1613 cmplz_set_consent(category, 'deny'); 1614 } 1615 cmplz_set_banner_status('dismissed'); 1616 cmplz_fire_categories_event(); 1617 cmplz_track_status(); 1618 } 1619 } 1620 } 1621 1622}); 1623 1624cmplz_add_event('click', '.cmplz-deny', function(e){ 1625 e.preventDefault(); 1626 cmplz_set_banner_status('dismissed'); 1627 cmplz_deny_all(); 1628 1629}); 1630 1631cmplz_add_event('click', 'button.cmplz-manage-settings', function(e){ 1632 e.preventDefault(); 1633 var catsContainer = document.querySelector('.cmplz-cookiebanner .cmplz-categories'); 1634 var saveSettings = document.querySelector('.cmplz-save-settings'); 1635 var manageSettings = document.querySelector('button.cmplz-manage-settings'); 1636 if ( !cmplz_is_hidden(catsContainer) ){ 1637 saveSettings.style.display='none'; 1638 manageSettings.style.display = 'block'; 1639 catsContainer.style.display='none'; 1640 } else { 1641 saveSettings.style.display = 'block'; 1642 manageSettings.style.display='none'; 1643 catsContainer.style.display = 'block'; 1644 } 1645}); 1646 1647cmplz_add_event('click', 'button.cmplz-manage-consent', function(e){ 1648 e.preventDefault(); 1649 cmplz_set_banner_status('show'); 1650}); 1651 1652/* 1653 * Handle dismiss on scroll and dismiss on timeout 1654 */ 1655function cmplz_set_up_auto_dismiss() { 1656 if ( complianz.consenttype === 'optout' ) { 1657 if ( complianz.dismiss_on_scroll==1 ) { 1658 var onWindowScroll = function(evt) { 1659 if (window.pageYOffset > Math.floor(400)) { 1660 cmplz_set_banner_status('dismissed'); 1661 cmplz_fire_categories_event(); 1662 cmplz_track_status(); 1663 window.removeEventListener('scroll', onWindowScroll); 1664 this.onWindowScroll = null; 1665 } 1666 }; 1667 window.addEventListener('scroll', onWindowScroll); 1668 } 1669 1670 var delay = parseInt(complianz.dismiss_timeout); 1671 if ( delay > 0 ) { 1672 var cmplzDismissTimeout = window.setTimeout(function () { 1673 cmplz_set_banner_status('dismissed'); 1674 cmplz_fire_categories_event(); 1675 cmplz_track_status(); 1676 }, Math.floor(delay)); 1677 } 1678 } 1679} 1680 1681/* 1682 * Fire a event wich passes all consented categories 1683 * Separated from the actual category consent because we want to bundle it in one event 1684 */ 1685function cmplz_fire_categories_event(){ 1686 let details = new Object(); 1687 details.category = cmplz_highest_accepted_category(); 1688 details.categories = cmplz_accepted_categories(); 1689 details.region = complianz.region; 1690 let event = new CustomEvent('cmplz_fire_categories', { detail: details }); 1691 document.dispatchEvent(event); 1692} 1693/* 1694 * Track the status of current consent 1695 * @param status 1696 */ 1697 1698function cmplz_track_status( status ) { 1699 var cats = []; 1700 status = typeof status !== 'undefined' ? status : false; 1701 1702 let event = new CustomEvent('cmplz_track_status', { detail: status }); 1703 document.dispatchEvent(event); 1704 1705 if ( !status ) { 1706 cats = cmplz_accepted_categories(); 1707 } else { 1708 cats = [status]; 1709 } 1710 cmplz_set_category_as_body_class(); 1711 var saved_cats, saved_services; 1712 try {saved_cats = JSON.parse(cmplz_get_cookie('saved_categories'));} catch (e) {saved_cats = {};} 1713 try {saved_services = JSON.parse(cmplz_get_cookie('saved_services'));} catch (e) {saved_services = {};} 1714 var consented_services = cmplz_get_all_service_consents(); 1715 1716 //compare current cats with saved cats. When there are no changes, do nothing. 1717 if (cmplz_equals(saved_cats, cats) && cmplz_equals(saved_services, consented_services)) { 1718 return; 1719 } 1720 1721 if ( complianz.store_consent != 1 || cmplz_is_bot() || cmplz_is_speedbot() ) { 1722 return; 1723 } 1724 1725 //keep track of the fact that the status was saved at least once 1726 cmplz_set_cookie('saved_categories', JSON.stringify(cats)); 1727 cmplz_set_cookie('saved_services', JSON.stringify(consented_services)); 1728 cmplz_consent_stored_once = true; 1729 1730 let data; 1731 var request = new XMLHttpRequest(); 1732 request.open('POST', complianz.url+'track', true); 1733 data = { 1734 'consented_categories': cats, 1735 'consented_services':consented_services, 1736 'consenttype': window.wp_consent_type,//store the source consenttype, as our complianz.consenttype will not include optinstats. 1737 }; 1738 1739 request.setRequestHeader('Content-type', 'application/json'); 1740 request.send(JSON.stringify(data)); 1741 1742} 1743 1744/* 1745 * Get accepted categories 1746 * 1747 * @returns {string} 1748 */ 1749function cmplz_accepted_categories() { 1750 var consentedCategories = cmplz_categories; 1751 var consentedTemp = []; 1752 1753 //because array filter changes keys, we make a temp arr 1754 for (var key in consentedCategories) { 1755 if ( consentedCategories.hasOwnProperty(key) ) { 1756 var category = consentedCategories[key]; 1757 if (cmplz_has_consent(category)) { 1758 consentedTemp.push(category); 1759 } 1760 } 1761 } 1762 1763 consentedCategories = consentedCategories.filter(function(value, index, consentedCategories){ 1764 return cmplz_in_array(value, consentedTemp); 1765 }); 1766 return consentedCategories; 1767} 1768 1769/* 1770 * Enable the checkbox for each category which was enabled 1771 * 1772 * */ 1773 1774function cmplz_sync_category_checkboxes() { 1775 for ( var key in cmplz_categories ) { 1776 if ( cmplz_categories.hasOwnProperty(key) ) { 1777 var category = cmplz_categories[key]; 1778 if ( cmplz_has_consent(category) || category === 'functional' ) {
1779 document.querySelectorAll('input.cmplz-' + category).forEach(obj => { 1780 obj.checked = true; 1781 }); 1782 } else { 1783 document.querySelectorAll('input.cmplz-' + category).forEach(obj => { 1784 obj.checked = false; 1785 }); 1786 } 1787 } 1788 1789 document.querySelectorAll('.cmplz-accept-service').forEach(obj => { 1790 let service = obj.getAttribute('data-service'); 1791 let category = obj.getAttribute('data-category'); 1792 if ( cmplz_has_service_consent( service, category ) ) { 1793 obj.checked = true; 1794 } else if ( cmplz_is_service_denied( service ) ) { 1795 obj.checked = false; 1796 } else { 1797 //no consent on service level, check if it's category has consent. 1798 let category = obj.getAttribute('data-category' ); 1799 obj.checked = !!cmplz_has_consent(category); 1800 } 1801 }); 1802 } 1803} 1804 1805/* 1806 * Merge two objects 1807 * 1808 * */ 1809 1810function cmplz_merge_object(userdata, ajax_data) { 1811 var output = []; 1812 //first, we fill the important data. 1813 for (key in ajax_data) { 1814 if (ajax_data.hasOwnProperty(key)) output[key] = ajax_data[key]; 1815 } 1816 1817 //conditionally add static data 1818 for (var key in userdata) { 1819 //only add if not in ajax_data 1820 if (!ajax_data.hasOwnProperty(key) || typeof ajax_data[key] === 'undefined') { 1821 if (userdata.hasOwnProperty(key)) output[key] = userdata[key]; 1822 } 1823 } 1824 1825 return output; 1826} 1827 1828/* 1829 * If current cookie policy has changed, reset cookie consent 1830 * 1831 * */ 1832 1833function cmplz_check_cookie_policy_id() { 1834 var user_policy_id = cmplz_get_cookie('policy_id'); 1835 if (user_policy_id && (complianz.current_policy_id !== user_policy_id) ) { 1836 cmplz_clear_cookies('cmplz'); 1837 } 1838} 1839 1840/* 1841 * Clear all our own cookies, to make sure path issues are resolved. 1842 * 1843 * 1844 */ 1845function cmplz_clear_cookies(cookie_part){ 1846 var foundCookie = false; 1847 1848 if (typeof document === 'undefined') { 1849 return foundCookie; 1850 } 1851 var secure = ";secure"; 1852 var date = new Date(); 1853 date.setTime(date.getTime() - (24 * 60 * 60 * 1000)); 1854 var expires = ";expires=" + date.toGMTString(); 1855 if (window.location.protocol !== "https:") secure = ''; 1856 let cookies = document.cookie.split("; "); 1857 let pathname = location.pathname; 1858 let pathParts = pathname.replace(/^\/|\/$/g, '').split('/'); 1859 1860 //loop through all cookies 1861 for (var i = 0; i < cookies.length; i++) { 1862 let cookieName = cookies[i].split(";")[0].split("=")[0]; 1863 let host = window.location.hostname; 1864 var domainParts = host.split("."); 1865 //if we have more than one result in the array, we can skip the last one, as it will be the .com/.org extension 1866 let skip_last = domainParts.length > 1; 1867 //if the cookie contains cookie_part, try to delete it 1868 if ( cookieName.indexOf(cookie_part) !==-1 ) { 1869 foundCookie = true; 1870 let cookieBaseDomain = encodeURIComponent(cookieName) + '=;SameSite=Lax' + secure + expires +';domain=;path='; 1871 document.cookie = cookieBaseDomain + '/'; 1872 //and on paths on root 1873 while ( pathParts.length > 0) { 1874 var path = pathParts.join('/'); 1875 if ( path.length>0 ) { 1876 document.cookie = cookieBaseDomain + '/' + path; 1877 document.cookie = cookieBaseDomain + '/' + path + '/'; 1878 } 1879 pathParts.pop(); 1880 }; 1881 while ( domainParts.length > 0) { 1882 let cookieBase = encodeURIComponent(cookieName) + '=;SameSite=Lax' + secure + expires +';domain=.' + domainParts.join('.') + ';path='; 1883 document.cookie = cookieBase+ '/'; 1884 while (pathParts.length > 0) { 1885 var path = pathParts.join('/'); 1886 if ( path.length>0 ) { 1887 document.cookie = cookieBase + '/' + path; 1888 document.cookie = cookieBase + '/' + path + '/'; 1889 } 1890 pathParts.pop(); 1891 }; 1892 1893 domainParts.shift(); 1894 //prevents setting cookies on .com/.org 1895 if (skip_last && domainParts.length==1) domainParts.shift(); 1896 } 1897 } 1898 } 1899 1900 //to prevent a double reload, we preserve the cookie policy id. 1901 cmplz_set_accepted_cookie_policy_id(); 1902 return foundCookie; 1903} 1904 1905/* 1906 * 1907 * If a policy is accepted, save this in the user policy id 1908 * 1909 * */ 1910 1911function cmplz_set_accepted_cookie_policy_id() { 1912 cmplz_set_cookie('policy_id', complianz.current_policy_id); 1913} 1914 1915/* 1916 * For supported integrations, initialize the not consented state 1917 * 1918 * */ 1919 1920function cmplz_integrations_init() { 1921 var cookiesToSet = complianz.set_cookies; 1922 //check if we have scripts that need to be set to true on init. 1923 for (var key in cookiesToSet) {
1924 if (cookiesToSet.hasOwnProperty(key) && cookiesToSet[key][1] === '1') { 1925 cmplz_set_cookie(key, cookiesToSet[key][1], false); 1926 } 1927 } 1928} 1929 1930/* 1931 * For supported integrations, revoke consent 1932 * 1933 * */ 1934function cmplz_integrations_revoke() { 1935 var cookiesToSet = complianz.set_cookies; 1936 for (var key in cookiesToSet) { 1937 if (cookiesToSet.hasOwnProperty(key)) { 1938 cmplz_set_cookie(key, cookiesToSet[key][1], false); 1939 if ( cookiesToSet[key][1] == false ){ 1940 cmplz_clear_cookies(key); 1941 } 1942 } 1943 } 1944} 1945 1946/* 1947 * For supported integrations, set consent 1948 * 1949 * */ 1950 1951function cmplz_set_integrations_cookies() { 1952 var cookiesToSet = complianz.set_cookies; 1953 for (var key in cookiesToSet) { 1954 if (cookiesToSet.hasOwnProperty(key)) { 1955 cmplz_set_cookie(key, cookiesToSet[key][0], false); 1956 } 1957 } 1958} 1959 1960function cmplz_get_url_parameter(sPageURL, sParam) { 1961 if ( !sPageURL || typeof sPageURL === 'undefined' ) { 1962 return false; 1963 } 1964 1965 if ( sPageURL.indexOf('?')==-1) { 1966 return false; 1967 } 1968 1969 var queryString = sPageURL.split('?'); 1970 if (queryString.length == 1) return false; 1971 1972 var sURLVariables = queryString[1].split('&'), 1973 sParameterName, 1974 i; 1975 for (i = 0; i < sURLVariables.length; i++) { 1976 if ( sURLVariables.hasOwnProperty(i) ) { 1977 sParameterName = sURLVariables[i].split('='); 1978 if (sParameterName[0] === sParam) { 1979 return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]); 1980 } 1981 } 1982 } 1983 return false; 1984} 1985 1986/* 1987 * If the parameter cmplz_region_redirect =true is passed, find the user's region, and redirect. 1988 */ 1989function cmplz_maybe_auto_redirect() { 1990 var redirect = cmplz_get_url_parameter(window.location.href, 'cmplz_region_redirect'); 1991 var region = cmplz_get_url_parameter(window.location.href, 'cmplz-region'); 1992 if (redirect && !region) { 1993 window.location.href = window.location.href + '&cmplz-region=' + complianz.region; 1994 } 1995} 1996 1997/* 1998 * wrapper to set consent for wp consent API. If consent API is not active, do nothing 1999 * @param type 2000 * @param value 2001 */ 2002function cmplz_wp_set_consent(type, value) { 2003 //wp consent api integration 2004 if (typeof wp_set_consent == 'function') { 2005 wp_set_consent(type, value); 2006 } 2007} 2008 2009var cmplz_cookie_data = []; 2010var cmplzCleanCookieInterval; 2011function cmplz_start_clean(){ 2012 if ( complianz.clean_cookies == 1 ) { 2013 //check if it's already stored 2014 if (typeof (Storage) !== "undefined" ) { 2015 cmplz_cookie_data = JSON.parse( sessionStorage.getItem('cmplz_cookie_data') ); 2016 } 2017 //if not stored yet, load. As features in the user object can be changed on updates, we also check for the version 2018 if ( !cmplz_cookie_data || cmplz_cookie_data.length == 0 ) { 2019 var request = new XMLHttpRequest(); 2020 request.open('GET', complianz.url+'cookie_data', true); 2021 request.setRequestHeader('Content-type', 'application/json'); 2022 request.send(); 2023 request.onload = function() { 2024 cmplz_cookie_data = JSON.parse(request.response); 2025 sessionStorage.setItem('cmplz_cookie_data', JSON.stringify(cmplz_cookie_data) ); 2026 cmplz_setup_clean_interval(); 2027 }; 2028 } else { 2029 cmplz_setup_clean_interval(); 2030 } 2031 } 2032} 2033 2034/* 2035* Execute the cleanup of cookies 2036*/ 2037function cmplz_do_cleanup(){ 2038 let consent_categories = [ 2039 'preferences', 2040 'statistics', 2041 'marketing', 2042 ]; 2043 for (var i in consent_categories) { 2044 let category = consent_categories[i]; 2045 if ( !cmplz_has_consent(category) && cmplz_cookie_data.hasOwnProperty(category) ) { 2046 let services = cmplz_cookie_data[category]; 2047 for (var service in services) { 2048 if ( !cmplz_has_service_consent(service, category) ) { 2049 let cookies = services[service]; 2050 for (var j in cookies) { 2051 let item = cookies[j]; 2052 cmplz_clear_cookies(item); 2053 cmplz_clear_storage(item); 2054 } 2055 } 2056 } 2057 } 2058 } 2059} 2060 2061function cmplz_setup_clean_interval(){ 2062 // if the cookie data array is empty, return, nothing to do. 2063 if ( !cmplz_cookie_data ) { 2064 return; 2065 } 2066 //check if it's already activated 2067 if ( cmplzCleanCookieInterval ) { 2068 return; 2069 } 2070 //one straight away, then every second 2071 cmplz_do_cleanup(); 2072 cmplzCleanCookieInterval = setInterval(cmplz_do_cleanup, 1000 ); 2073} 2074 2075/* 2076 * Clear an item from either session or localstorage 2077 * @param item 2078 */ 2079function cmplz_clear_storage(item){ 2080 if (typeof (Storage) !== "undefined" ) { 2081 if ( localStorage.item ) { 2082 localStorage.removeItem(item); 2083 }
2084 if ( sessionStorage.item ) { 2085 sessionStorage.removeItem(item); 2086 } 2087 } 2088} 2089/* 2090 * Load revoke options 2091 */ 2092 2093function cmplz_load_manage_consent_container() { 2094 //don't load manage html code in the block editor 2095 let manage_consent_container = document.querySelector('.cmplz-manage-consent-container'); 2096 let is_block_editor = false;//document.querySelector('.wp-admin .cmplz-unlinked-mode'); 2097 if ( manage_consent_container && !is_block_editor ) { 2098 2099 var request = new XMLHttpRequest(); 2100 request.open('GET', complianz.url+'manage_consent_html?'+complianz.locale, true); 2101 request.setRequestHeader('Content-type', 'application/json'); 2102 request.send(); 2103 request.onload = function() { 2104 let html = JSON.parse(request.response); 2105 manage_consent_container.insertAdjacentHTML( 'beforeend', html ); 2106 cmplz_sync_category_checkboxes(); 2107 let nojavascript = document.querySelector('#cmplz-manage-consent-container-nojavascript') 2108 nojavascript.style.display = 'none'; 2109 manage_consent_container.style.display = 'block'; 2110 let event = new CustomEvent('cmplz_manage_consent_container_loaded'); 2111 document.dispatchEvent(event); 2112 }; 2113 } 2114} 2115 2116/* 2117 * Make slider radio's tabable 2118 */ 2119 2120cmplz_add_event('keypress', '.cmplz-banner-slider label', function(e){ 2121 var keycode = (e.keyCode ? e.keyCode : e.which); 2122 if (keycode == 32) { 2123 document.activeElement.click(); 2124 } 2125}); 2126 2127/* 2128 * Make close button closable with enter 2129 */ 2130cmplz_add_event('keypress', '.cmplz-cookiebanner .cmplz-header .cmplz-close', function(e){ 2131 var keycode = (e.keyCode ? e.keyCode : e.which); 2132 if ( keycode == 13 ) { 2133 document.activeElement.click(); 2134 } 2135}); 2136 2137/* 2138 * Compare two arrays 2139 * @param array 2140 * @returns {boolean} 2141 */ 2142function cmplz_equals (array_1, array_2) { 2143 if ( !Array.isArray(array_1) ) { 2144 array_1 = Object.keys(array_1); 2145 array_2 = Object.keys(array_2); 2146 } 2147 // if the other array is a falsy value, return 2148 if (!array_1 || !array_2) 2149 return false; 2150 2151 // compare lengths - can save a lot of time 2152 if (array_1.length != array_2.length) 2153 return false; 2154 2155 for (var i = 0, l=array_1.length; i < l; i++) { 2156 // Check if we have nested arrays 2157 if (array_1[i] instanceof Array && array_2[i] instanceof Array) { 2158 // recurse into the nested arrays 2159 if (!cmplz_equals(array_1[i], array_2[i])) 2160 return false; 2161 } 2162 else if (array_1[i] != array_2[i]) { 2163 // Warning - two different object instances will never be equal: {x:20} != {x:20} 2164 return false; 2165 } 2166 } 2167 return true; 2168} 2169 2170/* 2171* Copy all element atributes to the new element 2172*/ 2173function cmplzCopyAttributes(source, target) { 2174 return Array.from(source.attributes).forEach(attribute => { 2175 //don't copy the type attribute 2176 let excludes = ['type', 'data-service', 'data-category', 'async']; 2177 if ( !excludes.includes(attribute.nodeName) ) { 2178 target.setAttribute( 2179 attribute.nodeName, 2180 attribute.nodeValue, 2181 ); 2182 } 2183 }); 2184} 2185 2186/* 2187 * Hooked into jquery 2188 */ 2189let cmplz_has_wp_video = document.querySelector('.cmplz-wp-video-shortcode'); 2190let cmplz_times_checked = 0; 2191if ('undefined' != typeof window.jQuery) { 2192 jQuery(document).ready(function ($) { 2193 if ( cmplz_has_wp_video ) { 2194 document.addEventListener("cmplz_enable_category", function (consentData) { 2195 cmplz_activate_wp_video(); 2196 }); 2197 2198 var cmplzInterval = setInterval(function(){ 2199 cmplz_times_checked+=1; 2200 if ( document.querySelector('.cmplz-wp-video-shortcode') && cmplz_times_checked<100) { 2201 cmplz_activate_wp_video(); 2202 } else { 2203 clearInterval(cmplzInterval); 2204 } 2205 }, 500); 2206 } 2207 2208 /* 2209 * WordPress legacy shortcode 2210 */ 2211 function cmplz_activate_wp_video(again) { 2212 if ( !document.querySelector('.cmplz-wp-video-shortcode') ) { 2213 return; 2214 } 2215 let categories = cmplz_accepted_categories(); 2216 let services = cmplz_get_all_service_consents(); 2217 let selectorVideo = ''; 2218 let selectorVideos = []; 2219 for (var c_key in categories) { 2220 if (categories.hasOwnProperty(c_key)) { 2221 let category = categories[c_key]; 2222 if (category==='functional') { 2223 break; 2224 } 2225 selectorVideos.push('.cmplz-wp-video-shortcode[data-category='+category+']'); 2226 } 2227 } 2228 for (var s_key in services) { 2229 if (services.hasOwnProperty(s_key)) { 2230 selectorVideos.push('.cmplz-wp-video-shortcode[data-service=' + s_key + ']'); 2231 } 2232 } 2233 selectorVideo = selectorVideos.join(','); 2234 let should_initialize_video = false;
2235 if ( selectorVideo.length>0 ) { 2236 document.querySelectorAll(selectorVideo).forEach(obj => { 2237 should_initialize_video = true; 2238 obj.setAttribute('controls', 'controls'); 2239 obj.classList.add('wp-video-shortcode'); 2240 obj.classList.add('cmplz-processed'); 2241 obj.classList.remove('cmplz-wp-video-shortcode'); 2242 obj.closest('.cmplz-wp-video').classList.remove('cmplz-wp-video'); 2243 2244 let blocked_notice = obj.closest('.wp-video').querySelector('.cmplz-blocked-content-notice'); 2245 if (blocked_notice) { 2246 blocked_notice.parentElement.removeChild(blocked_notice); 2247 } 2248 obj.classList.remove('cmplz-blocked-content-container'); 2249 }); 2250 } 2251 2252 if ( should_initialize_video ) { 2253 //in normal setup, this should work. e.g. with primavera theme not, then we init per element. 2254 if (window.wp.mediaelement) { 2255 window.wp.mediaelement.initialize() 2256 } else { 2257 let settings={}; 2258 settings.videoWidth='100%'; 2259 settings.videoHeight='100%'; 2260 settings.enableAutosize=true; 2261 $( '.wp-video-shortcode' ).mediaelementplayer( settings ); 2262 } 2263 } 2264 } 2265 2266 /* 2267 * Activate fitvids on the parent element if active 2268 * a.o. Beaverbuilder 2269 */ 2270 2271 document.querySelectorAll('.cmplz-video').forEach(obj => { 2272 //turn obj into jquery object 2273 let $obj = $(obj); 2274 if (typeof $obj.parent().fitVids == 'function') { 2275 $obj.parent().fitVids(); 2276 } 2277 }); 2278 2279 /* 2280 * Activate fitvids on the parent element if active 2281 * a.o. Beaverbuilder 2282 */ 2283 $(document).on("cmplz_category_enabled", cmplz_enable_fitvids); 2284 function cmplz_enable_fitvids(data) { 2285 document.querySelectorAll('.cmplz-video').forEach(obj => { 2286 //turn obj into jquery object 2287 let $obj = $(obj); 2288 if (typeof $obj.parent().fitVids == 'function') { 2289 $obj.parent().fitVids(); 2290 } 2291 }); 2292 } 2293 2294 }); 2295}
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.