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 let cArr = document.cookie.split(';'); 124 for (let i = 0; i < cArr.length; i++) { 125 let c = cArr[i].trim(); 126 if (c.indexOf(name) == 0) 127 return c.substring(name.length, c.length); 128 } 129 130 return ""; 131} 132 133/** 134 * set a cookie 135 * @param name 136 * @param value 137 * @param use_prefix 138 */ 139 140window.cmplz_set_cookie = function(name, value, use_prefix) { 141 if (typeof document === 'undefined') { 142 return; 143 } 144 if (typeof use_prefix === 'undefined') { 145 use_prefix = true; 146 } 147 let secure = ";secure"; 148 let date = new Date(); 149 date.setTime(date.getTime() + (complianz.cookie_expiry * 24 * 60 * 60 * 1000)); 150 let expires = ";expires=" + date.toGMTString(); 151 152 if (window.location.protocol !== "https:") secure = ''; 153 154 let domain = cmplz_get_cookie_domain(); 155 if (domain.length > 0) { 156 domain = ";domain=" + domain; 157 } 158 let prefix = ''; 159 if ( use_prefix ) { 160 prefix = complianz.prefix; 161 } 162 document.cookie = prefix+name + "=" + value + ";SameSite=Lax" + secure + expires + domain + ";path="+cmplz_get_cookie_path(); 163} 164 165/** 166 * Check if needle occurs in the haystack 167 * @param needle 168 * @param haystack 169 * @returns {boolean} 170 */ 171window.cmplz_in_array = function(needle, haystack) { 172 let length = haystack.length; 173 for(let i = 0; i < length; i++) { 174 if(haystack[i] == needle) return true; 175 } 176 return false;
177} 178 179/** 180 * Retrieve the highest level of consent that has been given 181 * 182 * */ 183 184window.cmplz_highest_accepted_category = function() { 185 var consentedCategories = cmplz_accepted_categories(); 186 if (cmplz_in_array( 'marketing', consentedCategories )) { 187 return 'marketing'; 188 } 189 190 if (cmplz_in_array( 'statistics', consentedCategories )) { 191 return 'statistics'; 192 } 193 194 if (cmplz_in_array( 'preferences', consentedCategories )) { 195 return 'preferences'; 196 } 197 198 return 'functional'; 199} 200 201/** 202 * Accept all categories 203 */ 204window.cmplz_accept_all = function(){ 205 for (var key in cmplz_categories) { 206 if ( cmplz_categories.hasOwnProperty(key) ) { 207 cmplz_set_consent(cmplz_categories[key], 'allow'); 208 } 209 } 210} 211 212/** 213 * Sets all accepted categories as class in body 214 */ 215 216function cmplz_set_category_as_body_class() { 217 let classList = document.body.className.split(/\s+/); 218 for (let i = 0; i < classList.length; i++) { 219 if ( classList[i].indexOf('cmplz-') !== -1 && classList[i] !== 'cmplz-document' ) { 220 document.body.classList.remove( classList[i] ); 221 } 222 } 223 224 let cats = cmplz_accepted_categories(); 225 for (let i in cats) { 226 if ( cats.hasOwnProperty(i) ) { 227 document.body.classList.add('cmplz-' + cats[i]); 228 } 229 } 230 231 let services = cmplz_get_all_service_consents(); 232 for (let service in services) { 233 if ( services.hasOwnProperty(service) && services[service]) { 234 document.body.classList.add('cmplz-' + service); 235 } 236 } 237 238 document.body.classList.add('cmplz-' + complianz.region); 239 document.body.classList.add('cmplz-' + complianz.consenttype); 240 let event = new CustomEvent('cmplz_set_category_as_bodyclass'); 241 document.dispatchEvent(event); 242} 243 244function cmplz_append_css(css){ 245 let head = document.getElementsByTagName('head')[0]; 246 let style = document.createElement('style'); 247 style.setAttribute('type', 'text/css'); 248 if (style.styleSheet) { // IE 249 style.styleSheet.cssText = css; 250 } else { // the world 251 style.appendChild(document.createTextNode(css)); 252 } 253 head.appendChild(style); 254} 255 256function cmplz_load_css( path ) { 257 let fileref = document.createElement("link") 258 fileref.setAttribute("rel", "stylesheet") 259 fileref.setAttribute("type", "text/css") 260 fileref.setAttribute("href", path) 261 document.getElementsByTagName("head")[0].appendChild(fileref) 262} 263 264/** 265 * Run script, src or inline 266 * @param script //src or inline script 267 * @param category 268 */ 269 270function cmplz_run_script( script, category, type ) { 271 let fileref = document.createElement("script"); 272 fileref.setAttribute("type", "text/javascript"); 273 if ( type !== 'inline' ) { 274 fileref.setAttribute("src", script); 275 } else { 276 if (typeof script !== 'string') { 277 script = script.innerHTML; 278 } 279 fileref.innerHTML = script; 280 } 281 //check if already fired 282 if ( cmplz_in_array( script, cmplz_fired_scripts) ) { 283 return; 284 } 285 286 fileref.onload = function () { 287 cmplz_maybe_run_waiting_scripts(script, category); 288 cmplz_run_after_all_scripts(category); 289 } 290 291 try { 292 document.getElementsByTagName("head")[0].appendChild(fileref); 293 cmplz_fired_scripts.push(script); 294 } catch(exception) { 295 throw "Something went wrong " + exception + " while loading "+path; 296 } 297 cmplz_run_after_all_scripts(category); 298} 299 300 301/** 302 * Check if there are waiting scripts, and if so, run them. 303 * @param script //src or inline script 304 * @param category 305 */ 306 307function cmplz_maybe_run_waiting_scripts( script, category ){ 308 let waitingScript = cmplz_get_waiting_script(cmplz_waiting_scripts, script); 309 if ( waitingScript ) { 310 cmplz_run_script( waitingScript, category, 'src' ); 311 } 312 313 let waiting_inline_script = cmplz_get_waiting_script(cmplz_waiting_inline_scripts, script); 314 if (waiting_inline_script) { 315 cmplz_run_script(waiting_inline_script, category, 'inline'); 316 } 317 318 cmplz_run_after_all_scripts(category); 319} 320 321/** 322 * Set placeholder image as background on the parent div, set notice, and handle height. 323 * 324 * */ 325 326function cmplz_set_blocked_content_container() { 327 //to prevent this function to twice run on an element, we add an attribute to each element that has been processed. 328 //then skip elements with that element. 329 document.querySelectorAll('.cmplz-image').forEach(obj => { 330 if ( obj.classList.contains('cmplz-processed') ) { 331 return; 332 } 333 obj.classList.add('cmplz-processed' ); 334 let service = obj.getAttribute('data-service'); 335 let blocked_image_container = obj.parentElement; 336 blocked_image_container.classList.add('cmplz-blocked-content-container'); 337 let curIndex = blocked_image_container.getAttribute('data-placeholder_class_index'); 338 //handle browser native lazy load feature 339 if (obj.getAttribute('loading') === 'lazy' ) { 340 obj.removeAttribute('loading'); 341 obj.setAttribute('deferlazy', 1); 342 } 343 344 if ( curIndex == null ) { 345 cmplz_placeholder_class_index++; 346 blocked_image_container.classList.add('cmplz-placeholder-' + cmplz_placeholder_class_index); 347 blocked_image_container.classList.add('cmplz-blocked-content-container'); 348 blocked_image_container.setAttribute('data-placeholder_class_index', cmplz_placeholder_class_index); 349 //insert placeholder text 350 if ( blocked_image_container.querySelector(".cmplz-blocked-content-notice" ) == null) { 351 let placeholderText = complianz.placeholdertext; 352 if (typeof placeholderText !== 'undefined') {
353 let btn = cmplz_create_element('button', ''); 354 btn.innerText = placeholderText; 355 btn.classList.add('cmplz-blocked-content-notice'); 356 btn.classList.add('cmplz-accept-marketing'); 357 btn.setAttribute('data-service', service ); 358 btn.setAttribute('aria-label', service ); 359 blocked_image_container.appendChild( btn ); 360 } 361 } 362 } 363 364 365 }); 366 367 document.querySelectorAll('.cmplz-placeholder-element').forEach(obj => { 368 if ( obj.classList.contains('cmplz-processed') ) { 369 return; 370 } 371 obj.classList.add('cmplz-processed' ); 372 let service = obj.getAttribute('data-service'); 373 374 //we set this element as container with placeholder image 375 let blocked_content_container; 376 if ( obj.classList.contains('cmplz-iframe')) { 377 //handle browser native lazy load feature 378 if ( obj.getAttribute('loading') === 'lazy' ) { 379 obj.removeAttribute('loading'); 380 obj.setAttribute('deferlazy', 1); 381 } 382 blocked_content_container = obj.parentElement; 383 } else { 384 blocked_content_container = obj; 385 } 386 let curIndex = blocked_content_container.getAttribute('data-placeholder_class_index'); 387 //if the blocked content container class is already added, don't add it again 388 if ( curIndex == null ) { 389 cmplz_placeholder_class_index++; 390 blocked_content_container.classList.add('cmplz-placeholder-' + cmplz_placeholder_class_index); 391 blocked_content_container.classList.add('cmplz-blocked-content-container'); 392 blocked_content_container.setAttribute('data-placeholder_class_index', cmplz_placeholder_class_index); 393 //insert placeholder text 394 if ( blocked_content_container.querySelector( ".cmplz-blocked-content-notice" ) == null ) { 395 let placeholderText = complianz.placeholdertext; 396 if (typeof placeholderText !== 'undefined') { 397 let btn = cmplz_create_element('button', ''); 398 btn.innerText = placeholderText; 399 btn.classList.add('cmplz-blocked-content-notice'); 400 btn.classList.add('cmplz-accept-marketing'); 401 btn.setAttribute('data-service', service ); 402 btn.setAttribute('aria-label', service ); 403 blocked_content_container.appendChild( btn ); 404 } 405 } 406 407 //handle image size for video 408 let src = obj.getAttribute('data-placeholder-image'); 409 if (typeof src !== 'undefined' && src.length ) { 410 src = src.replace('url(', '').replace(')', '').replace(/\"/gi, ""); 411 cmplz_append_css('.cmplz-placeholder-' + cmplz_placeholder_class_index + ' {background-image: url(' + src + ') !important;}'); 412 cmplz_set_blocked_content_container_aspect_ratio(obj, src, cmplz_placeholder_class_index); 413 } 414 } 415 }); 416 417 /** 418 * 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. 419 * We're assuming that statistics scripts won't be loaded with ajax, so we only load marketing level scripts 420 * 421 */ 422 if ( cmplz_has_consent('marketing') ) { 423 cmplz_enable_category('marketing'); 424 } 425 426} 427 428/** 429 * Set the height of an image relative to the width, depending on the image widht/height aspect ratio. 430 * 431 * 432 * */ 433 434function cmplz_set_blocked_content_container_aspect_ratio(container, src, placeholder_class_index) { 435 if ( container == null ) return; 436 437 //we set the first parent div as container with placeholder image 438 let blocked_content_container = container.parentElement; 439 440 //handle image size for video 441 let img = new Image(); 442 img.addEventListener("load", function () { 443 let imgWidth = this.naturalWidth; 444 let imgHeight = this.naturalHeight; 445 446 //prevent division by zero. 447 if (imgWidth === 0) imgWidth = 1; 448 let w = blocked_content_container.clientWidth; 449 let h = imgHeight * (w / imgWidth); 450 451 let heightCSS = ''; 452 if (src.indexOf('placeholder.jpg') === -1) { 453 heightCSS = 'height:' + h + 'px;'; 454 } 455 cmplz_append_css('.cmplz-placeholder-' + placeholder_class_index + ' {' + heightCSS + '}'); 456 }); 457 img.src = src; 458} 459/** 460 * Keep window aspect ratio in sync when window resizes 461 * To lower the number of times this code is executed, it is done with a timeout. 462 * 463 * */ 464 465var cmplzResizeTimer; 466window.addEventListener('resize', function(event) { 467 clearTimeout(cmplzResizeTimer); 468 cmplzResizeTimer = setTimeout( cmplz_set_blocked_content_container, 500); 469}, true); 470 471/** 472 * we run this function also on an interval, because with ajax loaded content, the placeholders would otherwise not be handled. 473 */ 474if ( complianz.block_ajax_content == 1 ) { 475 setInterval(function () { 476 cmplz_set_blocked_content_container(); 477 }, 2000); 478} 479 480/** 481 * Enable scripts that were blocked 482 * 483 * */ 484 485function cmplz_enable_category(category, service) { 486 if ( complianz.tm_categories == 1 && category !== '') { 487 cmplz_run_tm_event(category); 488 } 489 490 service = typeof service !== 'undefined' ? service : 'do_not_match'; 491 if ( category === '' ) category = 'do_not_match'; 492 493 if ( category === 'functional' ) { 494 return; 495 } 496 //enable cookies for integrations 497 if ( category === 'marketing' ) { 498 cmplz_set_integrations_cookies(); 499 } 500 501 //remove accept cookie notice overlay 502 document.querySelectorAll('.cmplz-blocked-content-notice.cmplz-accept-'+category+', .cmplz-blocked-content-notice[data-service='+service+']').forEach(obj => { 503 obj.parentNode.removeChild(obj); 504 }); 505 506 document.querySelectorAll('[data-category='+category+'], [data-service='+service+']').forEach(obj => { 507 //if a category is activated, but this specific service is denied, skip. 508 let elementService = obj.getAttribute('data-service'); 509 if ( cmplz_is_service_denied(elementService)) { 510 return; 511 } 512 513 //if native class is included, it isn't blocked, so will have run already 514 if ( obj.getAttribute('data-category') === 'functional' ) { 515 return; 516 } 517 518 if ( obj.classList.contains('cmplz-activated') ) { 519 return; 520 } 521 522 let tagName = obj.tagName; 523 if (tagName==='STYLE'){ 524 obj.classList.add('cmplz-activated' ); 525 let src = obj.getAttribute('data-href'); 526 cmplz_load_css( src, category); 527 } else if (tagName ==='IMG'){ 528 obj.classList.add('cmplz-activated' ); 529 let src = obj.getAttribute('data-src-cmplz'); 530 obj.setAttribute('src', src); 531 //handle browser native lazy load feature 532 if ( obj.getAttribute('data-deferlazy') ) { 533 obj.setAttribute('loading', 'lazy'); 534 } 535 let blocked_content_container = obj.closest('.cmplz-blocked-content-container'); 536 let cssIndex = blocked_content_container.getAttribute('data-placeholder_class_index'); 537 blocked_content_container.classList.remove('cmplz-blocked-content-container'); 538 blocked_content_container.classList.remove('cmplz-placeholder-' + cssIndex); 539 } else if (tagName==='IFRAME'){ 540 obj.classList.add('cmplz-activated' ); 541 let src = obj.getAttribute('data-src-cmplz'); 542 //check if there's an autoplay value we need to pass on 543 let autoplay = cmplz_get_url_parameter(obj.getAttribute('src'), 'autoplay'); 544 if ( autoplay === '1' ) src = src + '&autoplay=1'; 545 546 obj.addEventListener('load', (event) => { 547 //handle browser native lazy load feature 548 if ( obj.getAttribute('data-deferlazy') ) { 549 obj.setAttribute('loading', 'lazy'); 550 } 551 552 //we get the closest, not the parent, because a script could have inserted a div in the meantime. 553 let blocked_content_container = obj.closest('.cmplz-blocked-content-container'); 554 let cssIndex = blocked_content_container.getAttribute('data-placeholder_class_index'); 555 blocked_content_container.classList.remove('cmplz-blocked-content-container'); 556 blocked_content_container.classList.remove('cmplz-placeholder-' + cssIndex); 557 obj.classList.remove('cmplz-iframe-styles'); 558 obj.classList.remove('cmplz-iframe'); 559 obj.classList.remove('video-wrap'); 560 }); 561 obj.setAttribute('src', src); 562 } else if (obj.classList.contains('cmplz-placeholder-element')) { 563 obj.classList.add('cmplz-activated' ); 564 //other services, no iframe, with placeholders 565 //remove the added classes 566 let cssIndex = obj.getAttribute('data-placeholder_class_index'); 567 obj.classList.remove('cmplz-blocked-content-container'); 568 obj.classList.remove('cmplz-placeholder-' + cssIndex); 569 } 570 571 let details = new Object(); 572 details.category = category; 573 details.service = service; 574 let event = new CustomEvent('cmplz_category_enabled', { detail: details }); 575 document.dispatchEvent(event); 576 }); 577 578 /** 579 * Let's activate the scripts 580 */ 581 582 //create list of waiting scripts 583 let scriptElements = document.querySelectorAll('script[data-category='+category+'], script[data-service='+service+']');
584 scriptElements.forEach(obj => { 585 let waitfor = obj.getAttribute('data-waitfor'); 586 let src = obj.getAttribute('src'); 587 if ( waitfor ) { 588 if ( src ) { 589 cmplz_waiting_scripts[waitfor] = src; 590 } else if ( obj.innerText.length > 0 ) { 591 cmplz_waiting_inline_scripts[waitfor] = obj; 592 } 593 } 594 }); 595 596 //scripts: set to text/javascript 597 scriptElements.forEach(obj => { 598 if ( obj.classList.contains('cmplz-activated') ) { 599 return; 600 } 601 obj.classList.add('cmplz-activated' ); 602 let src = obj.getAttribute('src'); 603 if ( src ) { 604 obj.setAttribute('type', 'text/javascript'); 605 //check if this src or txt is in a waiting script. If so, skip. 606 if ( cmplz_is_waiting_script(cmplz_waiting_scripts, src) ) { 607 return; 608 } 609 610 if ( obj.getAttribute('data-post_scribe_id') ) { 611 let psID = '#' + obj.getAttribute('data-post_scribe_id'); 612 let postScribeObj = document.querySelector(psID); 613 if ( postScribeObj ) { 614 postScribeObj.innerHtml(''); 615 postscribe(psID, '<script src=' + src + '></script>'); 616 } 617 } else { 618 cmplz_run_script(src, category, 'src' ); 619 } 620 621 } else if (obj.innerText.length > 0 ) { 622 //check if this src or txt is in a waiting script. If so, skip. 623 if (cmplz_is_waiting_script(cmplz_waiting_inline_scripts, obj.innerText )) { 624 return; 625 } 626 627 cmplz_run_script( obj.innerText, category, 'inline' ); 628 } 629 }); 630 631 //fire an event so custom scripts can hook into this. 632 let details = new Object(); 633 details.category = category; 634 details.categories = cmplz_accepted_categories(); 635 details.services = cmplz_get_all_service_consents(); 636 details.region = complianz.region; 637 let event = new CustomEvent('cmplz_enable_category', { detail: details }); 638 document.dispatchEvent(event); 639 640 //if there are no blockable scripts at all, we still want to provide a hook 641 //in most cases, this script fires too early, and won't run yet. In that 642 //case it's run from the script activation callbacks. 643 cmplz_run_after_all_scripts(category); 644} 645 646 647 648/** 649 * check if the passed source has a waiting script that should be executed, and return it if so. 650 * @param waiting_scripts 651 * @param src 652 * @returns {*} 653 */ 654 655function cmplz_get_waiting_script(waiting_scripts, src) { 656 for (let waitfor in waiting_scripts) { 657 if ( waiting_scripts.hasOwnProperty(waitfor)) { 658 let waitingScript;//recaptcha/api.js, waitfor="gregaptcha" 659 if (waiting_scripts.hasOwnProperty(waitfor)) { 660 waitingScript = waiting_scripts[waitfor]; 661 if (typeof waitingScript !== 'string') { 662 waitingScript = waitingScript.innerText; 663 } 664 if (src.indexOf(waitfor) !== -1) { 665 let output = waiting_scripts[waitfor]; 666 delete waiting_scripts[waitfor]; 667 return output; 668 } 669 } 670 } 671 } 672 673 return false; 674} 675 676/** 677 * Because we need a key=>value array in javascript, the .length check for an empty array doesn't work. 678 * @param arr 679 * @returns {boolean} 680 */ 681function cmplz_array_is_empty(arr) { 682 for (let key in arr) { 683 if (arr.hasOwnProperty(key)) { 684 return false; 685 } 686 } 687 688 return true; 689} 690 691/** 692 * Check if the passed src or script is waiting for another script and should not execute 693 * @param waiting_scripts 694 * @param srcOrScript 695 */ 696 697function cmplz_is_waiting_script(waiting_scripts, srcOrScript) { 698 for (let waitfor in waiting_scripts) { 699 if ( waiting_scripts.hasOwnProperty(waitfor) ) { 700 let waitingScript = waiting_scripts[waitfor]; 701 if (typeof waitingScript !== 'string') waitingScript = waitingScript.innerText; 702 703 if (srcOrScript.indexOf(waitingScript) !== -1 || waitingScript.indexOf(srcOrScript) !== -1) { 704 return true; 705 } 706 } 707 } 708 return false; 709} 710 711/** 712 * if all scripts have been executed, fire a hook. 713 */ 714 715function cmplz_run_after_all_scripts(category) { 716 if (!cmplz_all_scripts_hook_fired && cmplz_array_is_empty(cmplz_waiting_inline_scripts) && cmplz_array_is_empty(cmplz_waiting_scripts) ) { 717 let event = new CustomEvent('cmplz_run_after_all_scripts', { detail: category }); 718 document.dispatchEvent(event); 719 cmplz_all_scripts_hook_fired = true; 720 } 721} 722 723/** 724 * Fire an event in Tag Manager 725 * 726 * 727 * */ 728 729let cmplz_fired_events = []; 730function cmplz_run_tm_event(category) { 731 if (cmplz_fired_events.indexOf(category) === -1) { 732 cmplz_fired_events.push(category); 733 window.dataLayer = window.dataLayer || []; 734 window.dataLayer.push({ 735 'event': complianz.prefix+'event_'+category 736 }); 737 let event = new CustomEvent('cmplz_tag_manager_event', { detail: category }); 738 document.dispatchEvent(event); 739 } 740} 741 742window.conditionally_show_banner = function() { 743 //merge userdata with complianz data, in case a b testing is used with user specific cookie banner data 744 //objects are merged so user_data will override data in complianz object 745 complianz = cmplz_merge_object( complianz, cmplz_user_data ); 746 //check if we need to redirect to another legal document, for a specific region 747 cmplz_maybe_auto_redirect(); 748 cmplz_set_blocked_content_container(); 749 750 /** 751 * Integration with WordPress, tell what kind of consent type we're using, then fire an event 752 */ 753 754 window.wp_consent_type = complianz.consenttype; 755 let event = new CustomEvent('wp_consent_type_defined'); 756 document.dispatchEvent( event ); 757 event = new CustomEvent('cmplz_before_cookiebanner' ); 758 document.dispatchEvent(event); 759 if ( complianz.forceEnableStats == 1 ) { 760 cmplz_set_consent('statistics', 'allow'); 761 } 762 763 let rev_cats = cmplz_categories.reverse(); 764 for (let key in rev_cats) { 765 if ( rev_cats.hasOwnProperty(key) ) { 766 let category = cmplz_categories[key]; 767 if (cmplz_has_consent(category)) { 768 cmplz_enable_category(category); 769 } 770 } 771 } 772 773 if ( cmplz_exists_service_consent() ) { 774 //if any service is enabled, allow the general services also, because some services are partially 'general' 775 cmplz_enable_category('', 'general'); 776 let services = cmplz_get_services_on_page(); 777 for (let key in services) { 778 if ( services.hasOwnProperty(key) ) { 779 let service = services[key]; 780 if (service.length == 0) continue; 781 if (cmplz_has_service_consent(service)) { 782 document.querySelectorAll('.cmplz-accept-service[data-service=' + service + ']').forEach(obj => { 783 obj.checked = true; 784 }); 785 786 cmplz_enable_category('', service); 787 } 788 } 789 } 790 } 791 792 cmplz_sync_category_checkboxes(); 793 cmplz_integrations_init(); 794 cmplz_check_cookie_policy_id(); 795 cmplz_set_up_auto_dismiss(); 796 797 //if we're on the cookie policy page, we dynamically load the applicable revoke checkbox 798 cmplz_load_manage_consent_container(); 799 800 event = new CustomEvent('cmplz_cookie_banner_data', { detail: complianz }); 801 document.dispatchEvent(event); 802 803 //if no categories were saved before, we do it now 804 if ( cmplz_get_cookie('saved_categories') === '' ) { 805 //for Non optin/optout visitors, and DNT users, we just track the no-warning option 806 if ( complianz.consenttype !== 'optin' && complianz.consenttype !== 'optout' ) { 807 cmplz_track_status( 'no_warning' ); 808 } else if ( complianz.do_not_track ) { 809 cmplz_track_status('do_not_track' ); 810 } 811 } 812 813 cmplz_set_category_as_body_class(); 814 //fire cats event, but do not fire a track, as we do this on exit. 815 cmplz_fire_categories_event(); 816 if (!complianz.do_not_track) { 817 if (complianz.consenttype === 'optin') { 818 if (complianz.forceEnableStats) { 819 cmplz_enable_category('statistics'); 820 } 821 console.log('opt-in'); 822 show_cookie_banner(); 823 } else if (complianz.consenttype === 'optout') { 824 console.log('opt-out'); 825 show_cookie_banner(); 826 } else {
827 console.log('other consent type, no cookie warning'); 828 //on other consent types, all scripts are enabled by default. 829 cmplz_accept_all(); 830 } 831 832 } else { 833 cmplz_track_status( 'do_not_track' ); 834 } 835} 836 837/** 838 * Get list of services active on the page 839 * @returns {*[]} 840 */ 841function cmplz_get_services_on_page(){ 842 let services=[]; 843 document.querySelectorAll('[data-service]').forEach(obj => { 844 let service = obj.getAttribute('data-service'); 845 if ( services.indexOf(service)==-1 ) { 846 services.push(service); 847 } 848 }); 849 return services; 850} 851 852/** 853 * Run the actual cookie warning 854 * 855 * */ 856 857 858window.show_cookie_banner = function () { 859 let disableCookiebanner = complianz.disable_cookiebanner || cmplz_is_speedbot(); 860 //do not show banner when manage consent area on cookie policy is visible 861 //when users use only the shortcode, the manage consent container is not active, but the dropdown cookie policy class is. 862 //when the complianz shortcode is used, the dropdown cookie policy class is loaded late because it's loaded with javascript. 863 let tmpDismissCookiebanner = false; 864 if ( document.querySelector('#cmplz-manage-consent-container') || document.querySelector('.cmplz-dropdown-cookiepolicy') ) { 865 tmpDismissCookiebanner = true; 866 } 867 868 var fragment = document.createDocumentFragment(); 869 let container = document.getElementById('cmplz-cookiebanner-container'); 870 if (container) { 871 fragment.appendChild(container); 872 document.body.prepend(fragment); 873 } 874 875 let link = document.createElement("link"); 876 let pageLinks = complianz.page_links[complianz.region]; 877 //get correct banner, based on banner_id 878 cmplz_banner = document.querySelector('.cmplz-cookiebanner.banner-'+complianz.user_banner_id+'.'+complianz.consenttype); 879 cmplz_manage_consent_button = document.querySelector('#cmplz-manage-consent .cmplz-manage-consent.manage-consent-'+complianz.user_banner_id); 880 let css_file_url = complianz.css_file.replace('type', complianz.consenttype ).replace('banner_id', complianz.user_banner_id); 881 if ( complianz.css_file.indexOf('cookiebanner/css/defaults/banner') != -1 ) { 882 console.log('Fallback default css file used. Please re-save banner settings, or check file writing permissions in uploads directory'); 883 } 884 link.href = css_file_url; 885 link.type = "text/css"; 886 link.rel = "stylesheet"; 887 link.onload = function () { 888 if ( !disableCookiebanner ) { 889 cmplz_banner.classList.remove('cmplz-hidden'); 890 cmplz_manage_consent_button.classList.remove('cmplz-hidden'); 891 } 892 } 893 document.getElementsByTagName("head")[0].appendChild(link); 894 if ( cmplz_banner && !disableCookiebanner ) { 895 cmplz_banner.querySelectorAll('.cmplz-links a:not(.cmplz-external), .cmplz-buttons a:not(.cmplz-external)').forEach(obj => { 896 let docElement = obj; 897 docElement.classList.add('cmplz-hidden'); 898 for (let pageType in pageLinks) { 899 if (pageLinks.hasOwnProperty(pageType) && docElement.classList.contains(pageType)) { 900 docElement.setAttribute('href', pageLinks[pageType]['url'] + docElement.getAttribute('data-relative_url')); 901 if (docElement.innerText === '{title}') { 902 docElement.innerText = cmplz_html_decode(pageLinks[pageType]['title']); 903 } 904 docElement.classList.remove('cmplz-hidden'); 905 } 906 } 907 }); 908 909 cmplz_set_banner_status(); 910 //we don't use the setBannerStatus function here, as we don't want to save it in a cookie now. 911 if ( tmpDismissCookiebanner ) { 912 cmplz_banner.classList.remove('cmplz-show'); 913 cmplz_banner.classList.add('cmplz-dismissed'); 914 cmplz_manage_consent_button.classList.remove('cmplz-dismissed'); 915 cmplz_manage_consent_button.classList.add('cmplz-show'); 916 } 917 } 918 919 let event = new CustomEvent('cmplz_cookie_warning_loaded', {detail: complianz.region}); 920 document.dispatchEvent(event); 921} 922/** 923 * Get the status of the banner: dismissed | show 924 * @returns {string} 925 */ 926window.cmplz_get_banner_status = function (){ 927 return cmplz_get_cookie('banner-status'); 928} 929 930/** 931 * Set the banner status so it will be either shown or dismissed, and store it in a cookie. 932 * @param status (optional) 933 */ 934 935window.cmplz_set_banner_status = function ( status ){ 936 let prevStatus = cmplz_get_cookie('banner-status'); 937 status = typeof status !== 'undefined' ? status : prevStatus; 938 if ( status !== prevStatus ) { 939 cmplz_set_cookie( 'banner-status', status ); 940 } 941 if (status.length===0){ 942 status = 'show'; 943 } 944 945 if (status==='show') { 946 prevStatus = 'dismissed'; 947 } else { 948 prevStatus = 'show'; 949 } 950 951 if ( cmplz_banner && status.length>0 ) { 952 cmplz_banner.classList.remove('cmplz-'+prevStatus); 953 cmplz_banner.classList.add('cmplz-'+status ); 954 if ( cmplz_manage_consent_button ) { 955 cmplz_manage_consent_button.classList.add('cmplz-'+prevStatus); 956 cmplz_manage_consent_button.classList.remove('cmplz-'+status); 957 } 958 } 959 960 if ( cmplz_banner_container && complianz.soft_cookiewall ) { 961 cmplz_banner_container.classList.remove('cmplz-'+prevStatus); 962 cmplz_banner_container.classList.add('cmplz-'+status );
963 cmplz_banner_container.classList.add('cmplz-soft-cookiewall'); 964 } 965 var event = new CustomEvent('cmplz_banner_status', { detail: status }); 966 document.dispatchEvent(event); 967} 968 969/** 970 * Check if current visitor is a bot 971 * 972 * @returns {boolean} 973 */ 974function cmplz_is_bot(){ 975 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)"; 976 var reBot = new RegExp(botPattern, 'i'); 977 var userAgent = navigator.userAgent; 978 if ( reBot.test(userAgent) ) { 979 return true; 980 } else { 981 return false; 982 } 983} 984/** 985 * Check if current visitor is a speedbot 986 * 987 * @returns {boolean} 988 */ 989function cmplz_is_speedbot(){ 990 var userAgent = navigator.userAgent; 991 var speedBotPattern = "(GTmetrix|pingdom|pingbot|Lighthouse)"; 992 var speedBot = new RegExp(speedBotPattern, 'i'); 993 994 if ( speedBot.test(userAgent) ) { 995 return true; 996 } else { 997 return false; 998 } 999} 1000 1001/** 1002 * Check if there is consent for a category or service 1003 * @param category 1004 * @returns {boolean} 1005 */ 1006window.cmplz_has_consent = function ( category ){ 1007 if ( cmplz_is_bot() ) { 1008 return true; 1009 } 1010 1011 if ( category === 'functional' ) return true; 1012 var has_consent, value; 1013 1014 /** 1015 * categories 1016 */ 1017 value = cmplz_get_cookie(category); 1018 if (complianz.consenttype === 'optout' && value === '') { 1019 //if it's opt out and no cookie is set we should return true 1020 has_consent = true; 1021 } else { 1022 //all other situations, return only true if value is allow 1023 has_consent = (value === 'allow'); 1024 } 1025 1026 return has_consent; 1027} 1028 1029/** 1030 * Check if a service has consent 1031 * @param service 1032 * @returns {boolean|*} 1033 */ 1034window.cmplz_is_service_denied = function ( service ) { 1035 //in opt out, there's no consent per service. so it's always true. 1036 if ( complianz.consenttype === 'optout' ) { 1037 return false; 1038 } 1039 1040 //Check if it's in the consented services cookie 1041 var consented_services_json = cmplz_get_cookie('consented_services'); 1042 var consented_services; 1043 try { 1044 consented_services = JSON.parse(consented_services_json); 1045 } catch (e) { 1046 consented_services = {}; 1047 } 1048 1049 if ( !consented_services.hasOwnProperty( service ) ){ 1050 return false; 1051 } else { 1052 return !consented_services[service]; 1053 } 1054} 1055 1056/** 1057 * Check if a service has consent 1058 * @param service 1059 * @returns {boolean|*} 1060 */ 1061window.cmplz_has_service_consent = function ( service ) { 1062 //in opt out, there's no consent per service. so it's always true. 1063 if ( complianz.consenttype === 'optout' ) { 1064 return true; 1065 } 1066 1067 //Check if it's in the consented services cookie 1068 var consented_services_json = cmplz_get_cookie('consented_services'); 1069 var consented_services; 1070 try { 1071 consented_services = JSON.parse(consented_services_json); 1072 } catch (e) { 1073 consented_services = {}; 1074 } 1075 1076 if ( !consented_services.hasOwnProperty( service ) ){ 1077 return false;
1078 } else { 1079 return consented_services[service]; 1080 } 1081} 1082 1083/** 1084 * check if there's at least one service with consent 1085 * @returns {boolean} 1086 */ 1087function cmplz_exists_service_consent(){ 1088 var consented_services_json = cmplz_get_cookie('consented_services'); 1089 var consented_services; 1090 try { 1091 consented_services = JSON.parse(consented_services_json); 1092 for (const key in consented_services) { 1093 if ( consented_services.hasOwnProperty(key) ) { 1094 if (consented_services[key] == true) { 1095 return true; 1096 } 1097 } 1098 } 1099 } catch (e) { 1100 return false; 1101 } 1102 return false; 1103} 1104 1105/** 1106 * Set consent for a service 1107 * @param service 1108 * @param consented 1109 */ 1110function cmplz_set_service_consent( service, consented ){ 1111 var consented_services_json = cmplz_get_cookie('consented_services'); 1112 var consented_services; 1113 try { 1114 consented_services = JSON.parse(consented_services_json); 1115 } catch (e) { 1116 consented_services = {}; 1117 } 1118 consented_services[service] = consented; 1119 cmplz_set_cookie('consented_services', JSON.stringify(consented_services) ); 1120} 1121 1122/** 1123 * Remove all service consents 1124 */ 1125function cmplz_clear_all_service_consents(){ 1126 cmplz_set_cookie('consented_services', ''); 1127} 1128 1129/** 1130 * Get all consented or denied services 1131 */ 1132 1133function cmplz_get_all_service_consents(){ 1134 var consented_services_json = cmplz_get_cookie('consented_services'); 1135 var consented_services; 1136 try { 1137 consented_services = JSON.parse(consented_services_json); 1138 } catch (e) { 1139 consented_services = {}; 1140 } 1141 return consented_services; 1142} 1143/** 1144 * Get cookie path 1145 * @returns {*} 1146 */ 1147function cmplz_get_cookie_path(){ 1148 return typeof complianz.cookie_path !== 'undefined' && complianz.cookie_path !== '' ? complianz.cookie_path : '/'; 1149} 1150 1151/** 1152 * retrieve domain to set the cookies on 1153 * @returns {string} 1154 */ 1155function cmplz_get_cookie_domain(){ 1156 var domain = ''; 1157 if ( complianz.set_cookies_on_root == 1 && complianz.cookie_domain.length>3){ 1158 domain = complianz.cookie_domain; 1159 } 1160 if (domain.indexOf('localhost') !== -1 ) { 1161 domain = ''; 1162 } 1163 return domain; 1164} 1165 1166/** 1167 * Set consent for a category 1168 * @param category 1169 * @param value 1170 */ 1171window.cmplz_set_consent = function (category, value){ 1172 cmplz_set_accepted_cookie_policy_id(); 1173 var previous_value = cmplz_get_cookie(category); 1174 //do not trigger a change event if nothing has changed. 1175 if ( previous_value === value ) { 1176 return; 1177 } 1178 1179 //keep checkboxes in banner and on cookie policy in sync 1180 var checked = value === 'allow'; 1181 document.querySelectorAll('input.cmplz-'+category).forEach(obj => { 1182 obj.checked = checked; 1183 }); 1184 1185 cmplz_set_cookie(category, value); 1186 if ( value === 'allow' ) { 1187 cmplz_enable_category(category); 1188 } 1189 1190 cmplz_wp_set_consent(category, value); 1191 if ( category === 'statistics' ) { 1192 cmplz_wp_set_consent('statistics-anonymous', 'allow'); 1193 } 1194 1195 var details = new Object(); 1196 details.category = category; 1197 details.value = value; 1198 details.region = complianz.region; 1199 details.categories = cmplz_accepted_categories(); 1200 var event = new CustomEvent('cmplz_status_change', { detail: details }); 1201 document.dispatchEvent(event); 1202 1203 if ( category === 'marketing' && value === 'deny' ) { 1204 cmplz_integrations_revoke(); 1205 //give the code some time to finish, so our track status code can send a signal to the backend. 1206 setTimeout(function(){ 1207 location.reload() 1208 }, 500); 1209 } 1210} 1211 1212/** 1213 * We use ajax to check the consenttype based on region, otherwise caching could prevent the user specific warning 1214 * 1215 * */ 1216 1217var cmplz_user_data = []; 1218//check if it's already stored 1219if (typeof (Storage) !== "undefined" && sessionStorage.cmplz_user_data) { 1220 cmplz_user_data = JSON.parse(sessionStorage.cmplz_user_data); 1221} 1222 1223//if not stored yet, load. As features in the user object can be changed on updates, we also check for the version 1224if ( complianz.geoip == 1 && (cmplz_user_data.length == 0 || (cmplz_user_data.version !== complianz.version) || (cmplz_user_data.banner_version !== complianz.banner_version)) ) { 1225 var request = new XMLHttpRequest(); 1226 request.open('GET', complianz.url+'banner?'+complianz.locale, true); 1227 request.setRequestHeader('Content-type', 'application/json'); 1228 request.send(); 1229 request.onload = function() { 1230 cmplz_user_data = JSON.parse(request.response); 1231 sessionStorage.cmplz_user_data = JSON.stringify(cmplz_user_data); 1232 conditionally_show_banner(); 1233 }; 1234} else { 1235 conditionally_show_banner(); 1236} 1237 1238/** 1239 * when ab testing, or using records of consent, we want to keep track of the unique user id 1240 */ 1241 1242if ( complianz.store_consent == 1 ) { 1243 var cmplz_id_cookie = cmplz_get_cookie('id'); 1244 var cmplz_id_session = ''; 1245 var cmplz_id = ''; 1246 if (typeof (Storage) !== "undefined" && sessionStorage.cmplz_id) { 1247 cmplz_id_session = JSON.parse(sessionStorage.cmplz_id); 1248 } 1249 1250 if ( cmplz_id_cookie.length == 0 && cmplz_id_session.length > 0 ) { 1251 cmplz_id = cmplz_id_session; 1252 cmplz_set_cookie('id', cmplz_id ); 1253 } 1254 1255 if ( cmplz_id_cookie.length > 0 && cmplz_id_session.length == 0 ) { 1256 cmplz_id = cmplz_id_cookie; 1257 } 1258 1259 if ( typeof (Storage) !== "undefined" ) { 1260 sessionStorage.cmplz_id = JSON.stringify(cmplz_id); 1261 } 1262} 1263 1264// visibilitychange and pagehide work in more browsers hence we check if they are supported and try to use them 1265document.addEventListener('visibilitychange', function () { 1266 if ( document.visibilityState === 'hidden' ) { 1267 cmplz_track_status_end(); 1268 } 1269}); 1270window.addEventListener("pagehide", cmplz_track_status_end, false ); 1271window.addEventListener("beforeunload", cmplz_track_status_end, false ); 1272 1273function cmplz_track_status_end(){ 1274 if ( !cmplz_consent_stored_once ) { 1275 cmplz_track_status(); 1276 } 1277} 1278 1279/** 1280 * This creates an API which devs can use to trigger actions in complianz. 1281 */ 1282document.addEventListener('cmplz_consent_action', function (e) { 1283 cmplz_set_consent( e.detail.category , 'allow' ); 1284 cmplz_fire_categories_event(); 1285 cmplz_track_status(); 1286}); 1287 1288/** 1289 * Deny all categories, and reload if needed. 1290 */ 1291window.cmplz_deny_all = function(){ 1292 for (var key in cmplz_categories) { 1293 if ( cmplz_categories.hasOwnProperty(key) ) { 1294 cmplz_set_consent(cmplz_categories[key], 'deny'); 1295 } 1296 } 1297 var consentLevel = cmplz_highest_accepted_category(); 1298 var reload = false;
1299 1300 if (consentLevel !== 'functional' || cmplz_exists_service_consent() ) { 1301 reload = true; 1302 } 1303 if ( cmplz_clear_all_complianz_cookies('cmplz_service') ) { 1304 reload = true; 1305 } 1306 1307 //has to be after the check if should be reloaded, otherwise that check won't work. 1308 cmplz_clear_all_service_consents(); 1309 cmplz_integrations_revoke(); 1310 cmplz_fire_categories_event(); 1311 cmplz_track_status(); 1312 1313 var event = new CustomEvent('cmplz_revoke', { detail: reload }); 1314 document.dispatchEvent(event); 1315 1316 //we need to let the iab extension handle the reload, otherwise the consent revoke might not be ready yet. 1317 if ( !complianz.tcf_active && reload ) { 1318 location.reload(); 1319 } 1320} 1321 1322/** 1323 * For both opt-in and opt-out, clicking cmplz-accept should result in accepting all categories 1324 */ 1325cmplz_add_event('click', '.cmplz-accept', function(e){ 1326 e.preventDefault(); 1327 cmplz_accept_all(); 1328 cmplz_set_banner_status('dismissed'); 1329 cmplz_fire_categories_event(); 1330 cmplz_track_status(); 1331}); 1332 1333/** 1334 * Accept marketing cookies by clicking any other link cookie acceptance from a custom link 1335 */ 1336 1337cmplz_add_event('click', '.cmplz-accept-marketing', function(e){ 1338 e.preventDefault(); 1339 let obj = e.target; 1340 var service = obj.getAttribute('data-service'); 1341 if ( complianz.clean_cookies == 1 && typeof service !== 'undefined' && service ){ 1342 cmplz_set_service_consent(service, true); 1343 cmplz_enable_category('', 'general'); 1344 cmplz_enable_category('', service); 1345 } else { 1346 cmplz_enable_category('', 'general'); 1347 cmplz_set_consent('marketing', 'allow' ); 1348 } 1349 cmplz_set_banner_status('dismissed'); 1350 cmplz_fire_categories_event(); 1351 cmplz_track_status(); 1352}); 1353 1354 1355 1356/** 1357 * Accept a specific service 1358 */ 1359cmplz_add_event('click', '.cmplz-accept-service', function(e){ 1360 e.preventDefault(); 1361 let obj = e.target; 1362 //that is for the change event, for input checkboxes 1363 let tagName = obj.tagName; 1364 if ( tagName === 'INPUT' ) return; 1365 let service = obj.getAttribute('data-service'); 1366 if ( typeof service !== 'undefined' ){ 1367 cmplz_set_service_consent(service, true); 1368 cmplz_enable_category('', 'general'); 1369 cmplz_enable_category('', service); 1370 } 1371 cmplz_fire_categories_event(); 1372 cmplz_track_status(); 1373}); 1374 1375/** 1376 * Accept a specific service 1377 */ 1378cmplz_add_event('change', '.cmplz-accept-service', function(e){ 1379 let obj = e.target; 1380 let service = obj.getAttribute('data-service'); 1381 if ( typeof service !== 'undefined' ){ 1382 if ( obj.checked ){ 1383 cmplz_set_service_consent(service, true); 1384 cmplz_enable_category('', service); 1385 } else { 1386 cmplz_set_service_consent(service, false); 1387 //give our track status time to finish 1388 setTimeout(function(){ 1389 location.reload() 1390 }, 500); 1391 } 1392 } 1393 cmplz_fire_categories_event(); 1394 cmplz_track_status(); 1395}); 1396 1397 1398 1399/** 1400 * On the banner, clicking a category should fire the category only after the save button is clicked. 1401 * 1402 */ 1403cmplz_add_event('click', '.cmplz-save-preferences', function(e){ 1404 let obj = e.target; 1405 cmplz_banner = obj.closest('.cmplz-cookiebanner'); 1406 for (var key in cmplz_categories) { 1407 if ( cmplz_categories.hasOwnProperty(key) ) { 1408 var category = cmplz_categories[key]; 1409 var categoryElement = cmplz_banner.querySelector('input.cmplz-' + category); 1410 if (categoryElement) { 1411 if (categoryElement.checked) { 1412 cmplz_set_consent(category, 'allow'); 1413 } else { 1414 cmplz_set_consent(category, 'deny'); 1415 } 1416 } 1417 } 1418 } 1419 cmplz_set_banner_status('dismissed'); 1420 cmplz_fire_categories_event(); 1421 cmplz_track_status(); 1422}); 1423 1424cmplz_add_event('click', '.cmplz-close', function(e){ 1425 cmplz_set_banner_status('dismissed'); 1426}); 1427 1428cmplz_add_event('click', '.cmplz-view-preferences', function(e){ 1429 let obj = e.target; 1430 cmplz_banner = obj.closest('.cmplz-cookiebanner'); 1431 if ( cmplz_banner.querySelector('.cmplz-categories').classList.contains('cmplz-fade-in')) { 1432 cmplz_banner.classList.remove('cmplz-categories-visible'); 1433 cmplz_banner.querySelector('.cmplz-categories' ).classList.remove('cmplz-fade-in'); 1434 cmplz_banner.querySelector('.cmplz-view-preferences' ).style.display = 'block'; 1435 cmplz_banner.querySelector('.cmplz-save-preferences' ).style.display = 'none'; 1436 } else {
1437 cmplz_banner.classList.add('cmplz-categories-visible'); 1438 cmplz_banner.querySelector('.cmplz-categories' ).classList.add('cmplz-fade-in'); 1439 cmplz_banner.querySelector('.cmplz-view-preferences' ).style.display = 'none'; 1440 cmplz_banner.querySelector('.cmplz-save-preferences' ).style.display = 'block'; 1441 } 1442}); 1443/** 1444 * On the cookie policy, clicking a category should fire the category immediately 1445 * 1446 */ 1447cmplz_add_event('change', '.cmplz-manage-consent-container .cmplz-category', function(e){ 1448 for (var key in cmplz_categories) { 1449 if ( cmplz_categories.hasOwnProperty(key) ) { 1450 var category = cmplz_categories[key]; 1451 var categoryElement = document.querySelector('.cmplz-manage-consent-container input.cmplz-' + category); 1452 if (categoryElement) { 1453 if (categoryElement.checked) { 1454 cmplz_set_consent(category, 'allow'); 1455 } else { 1456 cmplz_set_consent(category, 'deny'); 1457 } 1458 cmplz_set_banner_status('dismissed'); 1459 cmplz_fire_categories_event(); 1460 cmplz_track_status(); 1461 } 1462 } 1463 } 1464 1465}); 1466 1467cmplz_add_event('click', '.cmplz-deny', function(e){ 1468 e.preventDefault(); 1469 cmplz_set_banner_status('dismissed'); 1470 cmplz_deny_all(); 1471 1472}); 1473 1474cmplz_add_event('click', 'button.cmplz-manage-settings', function(e){ 1475 e.preventDefault(); 1476 var catsContainer = document.querySelector('.cmplz-cookiebanner .cmplz-categories'); 1477 var saveSettings = document.querySelector('.cmplz-save-settings'); 1478 var manageSettings = document.querySelector('button.cmplz-manage-settings'); 1479 if ( !cmplz_is_hidden(catsContainer) ){ 1480 saveSettings.style.display='none'; 1481 manageSettings.style.display = 'block'; 1482 catsContainer.style.display='none'; 1483 } else { 1484 saveSettings.style.display = 'block'; 1485 manageSettings.style.display='none'; 1486 catsContainer.style.display = 'block'; 1487 } 1488}); 1489 1490cmplz_add_event('click', 'button.cmplz-manage-consent', function(e){ 1491 e.preventDefault(); 1492 cmplz_set_banner_status('show'); 1493}); 1494 1495/** 1496 * Handle dismiss on scroll and dismiss on timeout 1497 */ 1498function cmplz_set_up_auto_dismiss() { 1499 if ( complianz.consenttype === 'optout' ) { 1500 if ( complianz.dismiss_on_scroll==1 ) { 1501 var onWindowScroll = function(evt) { 1502 if (window.pageYOffset > Math.floor(400)) { 1503 cmplz_set_banner_status('dismissed'); 1504 cmplz_fire_categories_event(); 1505 cmplz_track_status(); 1506 window.removeEventListener('scroll', onWindowScroll); 1507 this.onWindowScroll = null; 1508 } 1509 }; 1510 window.addEventListener('scroll', onWindowScroll); 1511 } 1512 1513 var delay = parseInt(complianz.dismiss_timeout); 1514 if ( delay > 0 ) { 1515 var cmplzDismissTimeout = window.setTimeout(function () { 1516 cmplz_set_banner_status('dismissed'); 1517 cmplz_fire_categories_event(); 1518 cmplz_track_status(); 1519 }, Math.floor(delay)); 1520 } 1521 } 1522} 1523 1524function cmplz_fire_categories_event(){ 1525 let details = new Object(); 1526 details.category = cmplz_highest_accepted_category(); 1527 details.categories = cmplz_accepted_categories(); 1528 details.region = complianz.region; 1529 event = new CustomEvent('cmplz_fire_categories', { detail: details }); 1530 document.dispatchEvent(event); 1531} 1532/** 1533 * Track the status of current consent 1534 * @param status 1535 */ 1536 1537function cmplz_track_status( status ) { 1538 var cats = []; 1539 status = typeof status !== 'undefined' ? status : false; 1540 1541 var event = new CustomEvent('cmplz_track_status', { detail: status }); 1542 document.dispatchEvent(event); 1543 1544 if ( !status ) { 1545 cats = cmplz_accepted_categories(); 1546 } else { 1547 cats = [status]; 1548 } 1549 cmplz_set_category_as_body_class(); 1550 var saved_cats, saved_services; 1551 try {saved_cats = JSON.parse(cmplz_get_cookie('saved_categories'));} catch (e) {saved_cats = {};} 1552 try {saved_services = JSON.parse(cmplz_get_cookie('saved_services'));} catch (e) {saved_services = {};} 1553 var consented_services = cmplz_get_all_service_consents(); 1554 1555 //compare current cats with saved cats. When there are no changes, do nothing. 1556 if (cmplz_equals(saved_cats, cats) && cmplz_equals(saved_services, consented_services)) { 1557 return; 1558 } 1559 1560 if ( complianz.store_consent != 1 ) { 1561 return; 1562 } 1563 1564 //keep track of the fact that the status was saved at least once 1565 cmplz_set_cookie('saved_categories', JSON.stringify(cats)); 1566 cmplz_set_cookie('saved_services', JSON.stringify(consented_services)); 1567 cmplz_consent_stored_once = true; 1568 var request = new XMLHttpRequest(); 1569 request.open('POST', complianz.url+'track', true); 1570 var data = { 1571 'consented_categories': cats, 1572 'consented_services':consented_services, 1573 'consenttype': window.wp_consent_type,//store the source consenttype, as our complianz.consenttype will not include optinstats. 1574 }; 1575 1576 request.setRequestHeader('Content-type', 'application/json'); 1577 request.send(JSON.stringify(data)); 1578 1579} 1580 1581/** 1582 * Get accepted categories 1583 * 1584 * @returns {string} 1585 */ 1586function cmplz_accepted_categories() { 1587 var consentedCategories = cmplz_categories; 1588 var consentedTemp = []; 1589 1590 //because array filter changes keys, we make a temp arr 1591 for (var key in consentedCategories) { 1592 if ( consentedCategories.hasOwnProperty(key) ) { 1593 var category = consentedCategories[key]; 1594 if (cmplz_has_consent(category)) { 1595 consentedTemp.push(category); 1596 } 1597 } 1598 } 1599 1600 consentedCategories = consentedCategories.filter(function(value, index, consentedCategories){ 1601 return cmplz_in_array(value, consentedTemp); 1602 }); 1603 return consentedCategories; 1604} 1605 1606/** 1607 * Enable the checkbox for each category which was enabled 1608 * 1609 * */ 1610 1611function cmplz_sync_category_checkboxes() { 1612 for ( var key in cmplz_categories ) { 1613 if ( cmplz_categories.hasOwnProperty(key) ) { 1614 var category = cmplz_categories[key]; 1615 if (cmplz_has_consent(category) || category === 'functional') {
1616 document.querySelectorAll('input.cmplz-' + category).forEach(obj => { 1617 obj.checked = true; 1618 }); 1619 } else { 1620 document.querySelectorAll('input.cmplz-' + category).forEach(obj => { 1621 obj.checked = false; 1622 }); 1623 } 1624 } 1625 } 1626} 1627 1628/** 1629 * Merge two objects 1630 * 1631 * */ 1632 1633function cmplz_merge_object(userdata, ajax_data) { 1634 var output = []; 1635 //first, we fill the important data. 1636 for (key in ajax_data) { 1637 if (ajax_data.hasOwnProperty(key)) output[key] = ajax_data[key]; 1638 } 1639 1640 //conditionally add static data 1641 for (var key in userdata) { 1642 //only add if not in ajax_data 1643 if (!ajax_data.hasOwnProperty(key) || typeof ajax_data[key] === 'undefined') { 1644 if (userdata.hasOwnProperty(key)) output[key] = userdata[key]; 1645 } 1646 } 1647 1648 return output; 1649} 1650 1651/** 1652 * If current cookie policy has changed, reset cookie consent 1653 * 1654 * */ 1655 1656function cmplz_check_cookie_policy_id() { 1657 var user_policy_id = cmplz_get_cookie('policy_id'); 1658 if (user_policy_id && (complianz.current_policy_id !== user_policy_id) ) { 1659 cmplz_clear_all_complianz_cookies('cmplz'); 1660 } 1661} 1662 1663/** 1664 * Clear all our own cookies, to make sure path issues are resolved. 1665 * 1666 * 1667 */ 1668function cmplz_clear_all_complianz_cookies(cookie_part){ 1669 var foundCookie = false; 1670 1671 if (typeof document === 'undefined') { 1672 return foundCookie; 1673 } 1674 var secure = ";secure"; 1675 var date = new Date(); 1676 date.setTime(date.getTime() - (24 * 60 * 60 * 1000)); 1677 var expires = ";expires=" + date.toGMTString(); 1678 if (window.location.protocol !== "https:") secure = ''; 1679 (function () { 1680 var cookies = document.cookie.split("; "); 1681 for (var c = 0; c < cookies.length; c++) { 1682 var d = window.location.hostname.split("."); 1683 //if we have more than one result in the array, we can skip the last one, as it will be the .com/.org extension 1684 var skip_last = d.length > 1; 1685 while (d.length > 0) { 1686 var cookieName = cookies[c].split(";")[0].split("=")[0]; 1687 var p = location.pathname; 1688 p = p.replace(/^\/|\/$/g, '').split('/'); 1689 if ( cookieName.indexOf(cookie_part) !==-1 ) { 1690 foundCookie = true; 1691 var cookieBase = encodeURIComponent(cookieName) + '=;SameSite=Lax' + secure + expires +';domain=.' + d.join('.') + ';path='; 1692 var cookieBaseDomain = encodeURIComponent(cookieName) + '=;SameSite=Lax' + secure + expires +';domain=;path='; 1693 document.cookie = cookieBaseDomain + '/'; 1694 document.cookie = cookieBase+ '/'; 1695 while (p.length > 0) { 1696 var path = p.join('/'); 1697 if ( path.length>0 ) { 1698 document.cookie = cookieBase + '/' + path; 1699 document.cookie = cookieBaseDomain + '/' + path; 1700 document.cookie = cookieBase + '/' + path + '/'; 1701 document.cookie = cookieBaseDomain + '/' + path + '/'; 1702 } 1703 p.pop(); 1704 }; 1705 } 1706 d.shift(); 1707 //prevents setting cookies on .com/.org 1708 if (skip_last && d.length==1) d.shift(); 1709 } 1710 } 1711 })(); 1712 1713 //to prevent a double reload, we preserve the cookie policy id. 1714 cmplz_set_accepted_cookie_policy_id(); 1715 return foundCookie; 1716} 1717 1718/** 1719 * 1720 * If a policy is accepted, save this in the user policy id 1721 * 1722 * */ 1723 1724function cmplz_set_accepted_cookie_policy_id() { 1725 cmplz_set_cookie('policy_id', complianz.current_policy_id); 1726} 1727 1728/** 1729 * For supported integrations, initialize the not consented state 1730 * 1731 * */ 1732 1733function cmplz_integrations_init() { 1734 var cookiesToSet = complianz.set_cookies; 1735 //check if we have scripts that need to be set to true on init. 1736 for (var key in cookiesToSet) { 1737 if (cookiesToSet.hasOwnProperty(key) && cookiesToSet[key][1] === '1') { 1738 cmplz_set_cookie(key, cookiesToSet[key][1], false); 1739 } 1740 } 1741} 1742 1743/** 1744 * For supported integrations, revoke consent 1745 * 1746 * */ 1747function cmplz_integrations_revoke() { 1748 var cookiesToSet = complianz.set_cookies; 1749 for (var key in cookiesToSet) { 1750 if (cookiesToSet.hasOwnProperty(key)) { 1751 cmplz_set_cookie(key, cookiesToSet[key][1], false); 1752 if ( cookiesToSet[key][1] == false ){ 1753 cmplz_clear_all_complianz_cookies(key); 1754 } 1755 } 1756 } 1757} 1758 1759/** 1760 * For supported integrations, set consent 1761 * 1762 * */ 1763 1764function cmplz_set_integrations_cookies() { 1765 var cookiesToSet = complianz.set_cookies; 1766 for (var key in cookiesToSet) {
1767 if (cookiesToSet.hasOwnProperty(key)) { 1768 cmplz_set_cookie(key, cookiesToSet[key][0], false); 1769 } 1770 } 1771} 1772 1773 1774function cmplz_get_url_parameter(sPageURL, sParam) { 1775 if (typeof sPageURL === 'undefined') return false; 1776 1777 var queryString = sPageURL.split('?'); 1778 if (queryString.length == 1) return false; 1779 1780 var sURLVariables = queryString[1].split('&'), 1781 sParameterName, 1782 i; 1783 for (i = 0; i < sURLVariables.length; i++) { 1784 if ( sURLVariables.hasOwnProperty(i) ) { 1785 sParameterName = sURLVariables[i].split('='); 1786 if (sParameterName[0] === sParam) { 1787 return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]); 1788 } 1789 } 1790 } 1791 return false; 1792} 1793 1794/** 1795 * If the parameter cmplz_region_redirect =true is passed, find the user's region, and redirect. 1796 */ 1797function cmplz_maybe_auto_redirect() { 1798 var redirect = cmplz_get_url_parameter(window.location.href, 'cmplz_region_redirect'); 1799 var region = cmplz_get_url_parameter(window.location.href, 'cmplz-region'); 1800 if (redirect && !region) { 1801 window.location.href = window.location.href + '&cmplz-region=' + complianz.region; 1802 } 1803} 1804 1805/** 1806 * wrapper to set consent for wp consent API. If consent API is not active, do nothing 1807 * @param type 1808 * @param value 1809 */ 1810function cmplz_wp_set_consent(type, value) { 1811 //wp consent api integration 1812 if (typeof wp_set_consent == 'function') { 1813 wp_set_consent(type, value); 1814 } 1815} 1816 1817/** 1818 * Load revoke options 1819 */ 1820 1821function cmplz_load_manage_consent_container() { 1822 let manage_consent_container = document.querySelector('.cmplz-manage-consent-container'); 1823 if ( manage_consent_container ) { 1824 var request = new XMLHttpRequest(); 1825 request.open('GET', complianz.url+'manage_consent_html?'+complianz.locale, true); 1826 request.setRequestHeader('Content-type', 'application/json'); 1827 request.send(); 1828 request.onload = function() { 1829 let html = JSON.parse(request.response); 1830 manage_consent_container.insertAdjacentHTML( 'beforeend', html ); 1831 cmplz_sync_category_checkboxes(); 1832 let nojavascript = document.querySelector('#cmplz-manage-consent-container-nojavascript') 1833 nojavascript.style.display = 'none'; 1834 manage_consent_container.style.display = 'block'; 1835 event = new CustomEvent('cmplz_manage_consent_container_loaded'); 1836 document.dispatchEvent(event); 1837 }; 1838 } 1839} 1840 1841/** 1842 * Make slider radio's tabable 1843 */ 1844 1845cmplz_add_event('keypress', '.cmplz-banner-slider label', function(e){ 1846 var keycode = (e.keyCode ? e.keyCode : e.which); 1847 if (keycode == '32') { 1848 document.activeElement.click(); 1849 } 1850}); 1851 1852/** 1853 * Compare two arrays 1854 * @param array 1855 * @returns {boolean} 1856 */ 1857function cmplz_equals (array_1, array_2) { 1858 if ( !Array.isArray(array_1) ) { 1859 array_1 = Object.keys(array_1); 1860 array_2 = Object.keys(array_2); 1861 } 1862 // if the other array is a falsy value, return 1863 if (!array_1 || !array_2) 1864 return false; 1865 1866 // compare lengths - can save a lot of time 1867 if (array_1.length != array_2.length) 1868 return false; 1869 1870 for (var i = 0, l=array_1.length; i < l; i++) { 1871 // Check if we have nested arrays 1872 if (array_1[i] instanceof Array && array_2[i] instanceof Array) { 1873 // recurse into the nested arrays 1874 if (!cmplz_equals(array_1[i], array_2[i])) 1875 return false; 1876 } 1877 else if (array_1[i] != array_2[i]) { 1878 // Warning - two different object instances will never be equal: {x:20} != {x:20} 1879 return false; 1880 } 1881 } 1882 return true; 1883} 1884 1885 1886 1887/** 1888 * Hooked into jquery 1889 */ 1890if ('undefined' != typeof window.jQuery) { 1891 // jQuery present 1892 jQuery(document).ready(function ($) { 1893 /** 1894 * Activate fitvids on the parent element if active 1895 * a.o. Beaverbuilder 1896 */ 1897 $(document).on("cmplz_category_enabled", cmplz_enable_fitvids); 1898 function cmplz_enable_fitvids(data) { 1899 document.querySelectorAll('.cmplz-video').forEach(obj => { 1900 //turn obj into jquery object 1901 let $obj = $(obj); 1902 if (typeof $obj.parent().fitVids == 'function') { 1903 $obj.parent().fitVids(); 1904 } 1905 }); 1906 } 1907 }); 1908} 1909
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.