1/*! 2 * ============================================================== 3 * NÃO EDITAR A MINIFICAÃÃO. O ARQUIVO ORIGINAL ESTÃ EM 4 * /home/eduardo/thirdParties/cookieconsent/src/cookieconsent.js 5 * ============================================================== 6 * 7 * CookieConsent v2.9.0 8 * https://www.github.com/orestbida/cookieconsent 9 * Author Orest Bida 10 * Released under the MIT License 11 * Edited by: 12 * - Eduardo P. Gomez 13 */ 14globalThis.VisaoiCookies = { 15 allowed: [], 16 denied: [], 17 /** 18 * @type {{[key: string]: Array<function>}} 19 */ 20 stack: {}, 21 22 /** 23 * 24 * @param {string} category, 25 * @param {function} callback 26 */ 27 onAllow(category,callback) { 28 if(!this.stack[category]) this.stack[category] = []; 29 this.stack[category].push(callback); 30 } 31}; 32(function(){ 33 'use strict'; 34 /** 35 * @param {HTMLElement} [root] - [optional] element where the cookieconsent will be appended 36 * @returns {Object} cookieconsent object with API 37 */ 38 var CookieConsent = function(root){ 39 40 /** 41 * CHANGE THIS FLAG FALSE TO DISABLE console.log() 42 */ 43 var ENABLE_LOGS = true; 44 45 var _config = { 46 'mode': 'opt-in', // 'opt-in', 'opt-out' 47 'current_lang': 'en', 48 'auto_language': null, 49 'autorun': true, // run as soon as loaded 50 'page_scripts': true, 51 'hide_from_bots': true, 52 'cookie_name': 'cc_cookie', 53 'cookie_expiration': 182, // default: 6 months (in days) 54 'cookie_domain': window.location.hostname, // default: current domain 55 'cookie_path': '/', 56 'cookie_same_site': 'Lax', 57 'use_rfc_cookie': false, 58 'autoclear_cookies': true, 59 'revision': 0, 60 'script_selector': 'data-cookiecategory' 61 }; 62 var subdomain = false; 63 64 var 65 /** 66 * Object which holds the main methods/API (.show, .run, ...) 67 */ 68 _cookieconsent = {}, 69 70 /** 71 * Global user configuration object 72 */ 73 user_config, 74 75 /** 76 * Internal state variables 77 */ 78 saved_cookie_content = {}, 79 cookie_data = null, 80 81 /** 82 * @type {Date} 83 */ 84 consent_date, 85 86 /** 87 * @type {Date} 88 */ 89 last_consent_update, 90 91 /** 92 * @type {string} 93 */ 94 consent_uuid, 95 96 /** 97 * @type {boolean} 98 */ 99 invalid_consent = true, 100 101 consent_modal_exists = false, 102 consent_modal_visible = false, 103 104 settings_modal_visible = false, 105 clicked_inside_modal = false, 106 current_modal_focusable, 107 108 all_table_headers, 109 all_blocks, 110 111 // Helper callback functions 112 // (avoid calling "user_config['onAccept']" all the time) 113 onAccept, 114 onChange, 115 onFirstAction, 116 117 revision_enabled = false, 118 valid_revision = true, 119 revision_message = '', 120 121 // State variables for the autoclearCookies function 122 changed_settings = [], 123 reload_page = false; 124 125 /** 126 * Accept type: 127 * - "all" 128 * - "necessary" 129 * - "custom" 130 * @type {string} 131 */ 132 var accept_type; 133 134 /** 135 * Contains all accepted categories 136 * @type {string[]} 137 */ 138 var accepted_categories = []; 139 140 /** 141 * Contains all non-accepted (rejected) categories 142 * @type {string[]} 143 */ 144 var rejected_categories = []; 145 146 /** 147 * Contains all categories enabled by default 148 * @type {string[]} 149 */ 150 var default_enabled_categories = []; 151 152 // Don't run plugin (to avoid indexing its text content) if bot detected 153 var is_bot = false;
154 155 /** 156 * Save reference to the last focused element on the page 157 * (used later to restore focus when both modals are closed) 158 */ 159 var last_elem_before_modal; 160 var last_consent_modal_btn_focus; 161 162 /** 163 * Both of the arrays below have the same structure: 164 * [0] => holds reference to the FIRST focusable element inside modal 165 * [1] => holds reference to the LAST focusable element inside modal 166 */ 167 var consent_modal_focusable = []; 168 var settings_modal_focusable = []; 169 170 /** 171 * Keep track of enabled/disabled categories 172 * @type {boolean[]} 173 */ 174 var toggle_states = []; 175 176 /** 177 * Stores all available categories 178 * @type {string[]} 179 */ 180 var all_categories = []; 181 182 /** 183 * Keep track of readonly toggles 184 * @type {boolean[]} 185 */ 186 var readonly_categories = []; 187 188 /** 189 * Pointers to main dom elements (to avoid retrieving them later using document.getElementById) 190 */ 191 var 192 /** @type {HTMLElement} */ html_dom = document.documentElement, 193 /** @type {HTMLElement} */ main_container, 194 /** @type {HTMLElement} */ all_modals_container, 195 196 /** @type {HTMLElement} */ consent_modal, 197 /** @type {HTMLElement} */ consent_modal_title, 198 /** @type {HTMLElement} */ consent_modal_description, 199 /** @type {HTMLElement} */ consent_primary_btn, 200 /** @type {HTMLElement} */ consent_secondary_btn, 201 /** @type {HTMLElement} */ consent_buttons, 202 /** @type {HTMLElement} */ consent_modal_inner, 203 204 /** @type {HTMLElement} */ settings_container, 205 /** @type {HTMLElement} */ settings_inner, 206 /** @type {HTMLElement} */ settings_title, 207 /** @type {HTMLElement} */ settings_close_btn, 208 /** @type {HTMLElement} */ settings_blocks, 209 /** @type {HTMLElement} */ new_settings_blocks, 210 /** @type {HTMLElement} */ settings_buttons, 211 /** @type {HTMLElement} */ settings_save_btn, 212 /** @type {HTMLElement} */ settings_accept_all_btn, 213 /** @type {HTMLElement} */ settings_reject_all_btn; 214 215 /** 216 * Update config settings 217 * @param {Object} user_config 218 */ 219 var _setConfig = function(_user_config){ 220 221 /** 222 * Make user configuration globally available 223 */ 224 user_config = _user_config; 225 226 _log("CookieConsent [CONFIG]: received_config_settings ", user_config); 227 228 if(typeof user_config['cookie_expiration'] === "number") 229 _config.cookie_expiration = user_config['cookie_expiration']; 230 231 if(typeof user_config['cookie_necessary_only_expiration'] === "number") 232 _config.cookie_necessary_only_expiration = user_config['cookie_necessary_only_expiration']; 233 234 if(typeof user_config['autorun'] === "boolean") 235 _config.autorun = user_config['autorun']; 236 237 if(typeof user_config['cookie_domain'] === "string") 238 _config.cookie_domain = user_config['cookie_domain']; 239 240 if(typeof user_config['cookie_same_site'] === "string") 241 _config.cookie_same_site = user_config['cookie_same_site']; 242 243 if(typeof user_config['cookie_path'] === "string") 244 _config.cookie_path = user_config['cookie_path']; 245 246 if(typeof user_config['cookie_name'] === "string") 247 _config.cookie_name = user_config['cookie_name']; 248 249 if(typeof user_config['onAccept'] === "function") 250 onAccept = user_config['onAccept']; 251 252 if(typeof user_config['onFirstAction'] === "function") 253 onFirstAction = user_config['onFirstAction']; 254 255 if(typeof user_config['onChange'] === "function") 256 onChange = user_config['onChange']; 257 258 if(user_config['mode'] === 'opt-out') 259 _config.mode = 'opt-out'; 260
261 if(typeof user_config['revision'] === "number"){ 262 user_config['revision'] > -1 && (_config.revision = user_config['revision']); 263 revision_enabled = true; 264 } 265 266 if(typeof user_config['autoclear_cookies'] === "boolean") 267 _config.autoclear_cookies = user_config['autoclear_cookies']; 268 269 if(user_config['use_rfc_cookie'] === true) 270 _config.use_rfc_cookie = true; 271 272 if(typeof user_config['hide_from_bots'] === "boolean"){ 273 _config.hide_from_bots = user_config['hide_from_bots']; 274 } 275 276 if(_config.hide_from_bots){ 277 is_bot = navigator && 278 ((navigator.userAgent && /bot|crawl|spider|slurp|teoma/i.test(navigator.userAgent)) || navigator.webdriver); 279 } 280 281 _config.page_scripts = user_config['page_scripts'] === true; 282 283 if (user_config['auto_language'] === 'browser' || user_config['auto_language'] === true) { 284 _config.auto_language = 'browser'; 285 } else if (user_config['auto_language'] === 'document') { 286 _config.auto_language = 'document'; 287 } 288 289 _log("CookieConsent [LANG]: auto_language strategy is '" + _config.auto_language + "'"); 290 291 _config.current_lang = _resolveCurrentLang(user_config.languages, user_config['current_lang']); 292 } 293 294 /** 295 * Add an onClick listeners to all html elements with data-cc attribute 296 */ 297 var _addDataButtonListeners = function(elem){ 298 299 var _a = 'accept-'; 300 301 var show_settings = _getElements('c-settings'); 302 var accept_all = _getElements(_a + 'all'); 303 var accept_necessary = _getElements(_a + 'necessary'); 304 var accept_custom_selection = _getElements(_a + 'custom'); 305 306 for(var i=0; i<show_settings.length; i++){ 307 show_settings[i].setAttribute('aria-haspopup', 'dialog'); 308 _addEvent(show_settings[i], 'click', function(event){ 309 event.preventDefault(); 310 _cookieconsent.showSettings(0); 311 }); 312 } 313 314 for(i=0; i<accept_all.length; i++){ 315 _addEvent(accept_all[i], 'click', function(event){ 316 _acceptAction(event, 'all'); 317 }); 318 } 319 320 for(i=0; i<accept_custom_selection.length; i++){ 321 _addEvent(accept_custom_selection[i], 'click', function(event){ 322 _acceptAction(event); 323 }); 324 } 325 326 for(i=0; i<accept_necessary.length; i++){ 327 _addEvent(accept_necessary[i], 'click', function(event){ 328 _acceptAction(event, []); 329 }); 330 } 331 332 /** 333 * Return all elements with given data-cc role 334 * @param {string} data_role 335 * @returns {NodeListOf<Element>} 336 */ 337 function _getElements(data_role){ 338 return (elem || document).querySelectorAll('a[data-cc="' + data_role + '"], button[data-cc="' + data_role + '"]'); 339 } 340 341 /** 342 * Helper function: accept and then hide modals 343 * @param {PointerEvent} e source event 344 * @param {string} [accept_type] 345 */ 346 function _acceptAction(e, accept_type){ 347 e.preventDefault(); 348 _cookieconsent.accept(accept_type); 349 _cookieconsent.hideSettings(); 350 _cookieconsent.hide(); 351 } 352 } 353 354 /** 355 * Get a valid language (at least 1 must be defined) 356 * @param {string} lang - desired language 357 * @param {Object} all_languages - all defined languages 358 * @returns {string} validated language 359 */ 360 var _getValidatedLanguage = function(lang, all_languages){ 361 if(Object.prototype.hasOwnProperty.call(all_languages, lang)){ 362 return lang; 363 }else if(_getKeys(all_languages).length > 0){ 364 if(Object.prototype.hasOwnProperty.call(all_languages, _config.current_lang)){ 365 return _config.current_lang ; 366 }else{ 367 return _getKeys(all_languages)[0]; 368 } 369 } 370 } 371 372 /** 373 * Save reference to first and last focusable elements inside each modal 374 * to prevent losing focus while navigating with TAB 375 */ 376 var _getModalFocusableData = function(){ 377 378 /** 379 * Note: any of the below focusable elements, which has the attribute tabindex="-1" AND is either 380 * the first or last element of the modal, won't receive focus during "open/close" modal 381 */ 382 var allowed_focusable_types = ['[href]', 'button', 'input', 'details', '[tabindex="0"]']; 383 384 function _getAllFocusableElements(modal, _array){ 385 var focus_later=false, focus_first=false; 386 387 // ie might throw exception due to complex unsupported selector => a:not([tabindex="-1"]) 388 try{ 389 var focusable_elems = modal.querySelectorAll(allowed_focusable_types.join(':not([tabindex="-1"]), ')); 390 var attr, len=focusable_elems.length, i=0; 391 392 while(i < len){ 393 394 attr = focusable_elems[i].getAttribute('data-focus'); 395 396 if(!focus_first && attr === "1"){ 397 focus_first = focusable_elems[i]; 398 399 }else if(attr === "0"){ 400 focus_later = focusable_elems[i]; 401 if(!focus_first && focusable_elems[i+1].getAttribute('data-focus') !== "0"){ 402 focus_first = focusable_elems[i+1]; 403 } 404 } 405 406 i++; 407 } 408 409 }catch(e){ 410 return modal.querySelectorAll(allowed_focusable_types.join(', ')); 411 } 412 413 /** 414 * Save first and last elements (used to lock/trap focus inside modal) 415 */
416 _array[0] = focusable_elems[0]; 417 _array[1] = focusable_elems[focusable_elems.length - 1]; 418 _array[2] = focus_later; 419 _array[3] = focus_first; 420 } 421 422 /** 423 * Get settings modal'S all focusable elements 424 * Save first and last elements (used to lock/trap focus inside modal) 425 */ 426 _getAllFocusableElements(settings_inner, settings_modal_focusable); 427 428 /** 429 * If consent modal exists, do the same 430 */ 431 if(consent_modal_exists){ 432 _getAllFocusableElements(consent_modal, consent_modal_focusable); 433 } 434 } 435 436 var _createConsentModal = function(lang){ 437 438 if(user_config['force_consent'] === true) 439 _addClass(html_dom, 'force--consent'); 440 441 // Create modal if it doesn't exist 442 if(!consent_modal){ 443 444 consent_modal = _createNode('div'); 445 var consent_modal_inner_inner = _createNode('div'); 446 var overlay = _createNode('div'); 447 448 consent_modal.id = 'cm'; 449 consent_modal_inner_inner.id = 'c-inr-i'; 450 overlay.id = 'cm-ov'; 451 452 consent_modal.setAttribute('role', 'dialog'); 453 consent_modal.setAttribute('aria-modal', 'true'); 454 consent_modal.setAttribute('aria-hidden', 'false'); 455 consent_modal.setAttribute('aria-labelledby', 'c-ttl'); 456 consent_modal.setAttribute('aria-describedby', 'c-txt'); 457 458 // Append consent modal to main container 459 all_modals_container.appendChild(consent_modal); 460 all_modals_container.appendChild(overlay); 461 462 /** 463 * Make modal by default hidden to prevent weird page jumps/flashes (shown only once css is loaded) 464 */ 465 consent_modal.style.visibility = overlay.style.visibility = "hidden"; 466 overlay.style.opacity = 0; 467 } 468 469 // Use insertAdjacentHTML instead of innerHTML 470 var consent_modal_title_value = user_config.languages[lang]['consent_modal']['title']; 471 472 // Add title (if valid) 473 if(consent_modal_title_value){ 474 475 if(!consent_modal_title){ 476 consent_modal_title = _createNode('div'); 477 consent_modal_title.id = 'c-ttl'; 478 consent_modal_title.setAttribute('role', 'heading'); 479 consent_modal_title.setAttribute('aria-level', '2'); 480 consent_modal_inner_inner.appendChild(consent_modal_title); 481 } 482 483 consent_modal_title.innerHTML = consent_modal_title_value; 484 } 485 486 var description = user_config.languages[lang]['consent_modal']['description']; 487 488 if(revision_enabled){ 489 if(!valid_revision){ 490 description = description.replace("{{revision_message}}", revision_message || user_config.languages[lang]['consent_modal']['revision_message'] || ""); 491 }else{ 492 description = description.replace("{{revision_message}}", ""); 493 } 494 } 495 496 if(!consent_modal_description){ 497 consent_modal_description = _createNode('div'); 498 consent_modal_description.id = 'c-txt'; 499 consent_modal_inner_inner.appendChild(consent_modal_description); 500 } 501 502 // Set description content 503 consent_modal_description.innerHTML = description; 504 505 var primary_btn_data = user_config.languages[lang]['consent_modal']['primary_btn'], // accept current selection 506 secondary_btn_data = user_config.languages[lang]['consent_modal']['secondary_btn']; 507 508 // Add primary button if not falsy 509 if(primary_btn_data){ 510 511 if(!consent_primary_btn){ 512 consent_primary_btn = _createNode('button'); 513 consent_primary_btn.id = 'c-p-bn'; 514 consent_primary_btn.className = "c-bn"; 515 516 var _accept_type; 517 518 if(primary_btn_data['role'] === 'accept_all') 519 _accept_type = 'all' 520 521 _addEvent(consent_primary_btn, "click", function(){ 522 _cookieconsent.hide(); 523 _log("CookieConsent [ACCEPT]: cookie_consent was accepted!"); 524 _cookieconsent.accept(_accept_type); 525 }); 526 } 527 528 consent_primary_btn.innerHTML = user_config.languages[lang]['consent_modal']['primary_btn']['text']; 529 } 530 531 // Add secondary button if not falsy 532 if(secondary_btn_data){ 533 534 if(!consent_secondary_btn){ 535 consent_secondary_btn = _createNode('button'); 536 consent_secondary_btn.id = 'c-s-bn'; 537 consent_secondary_btn.className = "c-bn c_link"; 538 539 if(secondary_btn_data['role'] === 'accept_necessary'){ 540 _addEvent(consent_secondary_btn, 'click', function(){ 541 _cookieconsent.hide(); 542 _cookieconsent.accept([]); // accept necessary only 543 }); 544 }else{ 545 _addEvent(consent_secondary_btn, 'click', function(){ 546 _cookieconsent.showSettings(0); 547 }); 548 } 549 } 550 551 consent_secondary_btn.innerHTML = user_config.languages[lang]['consent_modal']['secondary_btn']['text']; 552 } 553 554 // Swap buttons 555 var gui_options_data = user_config['gui_options']; 556 557 if(!consent_modal_inner){ 558 consent_modal_inner = _createNode('div'); 559 consent_modal_inner.id = 'c-inr'; 560 561 consent_modal_inner.appendChild(consent_modal_inner_inner); 562 } 563 564 if(!consent_buttons){ 565 consent_buttons = _createNode('div'); 566 consent_buttons.id = "c-bns"; 567 568 if(gui_options_data && gui_options_data['consent_modal'] && gui_options_data['consent_modal']['swap_buttons'] === true){ 569 secondary_btn_data && consent_buttons.appendChild(consent_secondary_btn); 570 primary_btn_data && consent_buttons.appendChild(consent_primary_btn); 571 consent_buttons.className = 'swap'; 572 }else{ 573 primary_btn_data && consent_buttons.appendChild(consent_primary_btn); 574 secondary_btn_data && consent_buttons.appendChild(consent_secondary_btn); 575 } 576 577 (primary_btn_data || secondary_btn_data ) && consent_modal_inner.appendChild(consent_buttons); 578 consent_modal.appendChild(consent_modal_inner); 579 } 580 581 consent_modal_exists = true; 582 583 _addDataButtonListeners(consent_modal_inner); 584 } 585 586 var _createSettingsModal = function(lang){ 587 588 /** 589 * Create all consent_modal elements 590 */ 591 if(!settings_container){ 592 settings_container = _createNode('div'); 593 var settings_container_valign = _createNode('div'); 594 var settings = _createNode('div'); 595 var settings_container_inner = _createNode('div'); 596 settings_inner = _createNode('div'); 597 settings_title = _createNode('div'); 598 var settings_header = _createNode('div'); 599 settings_close_btn = _createNode('button'); 600 var settings_close_btn_container = _createNode('div'); 601 settings_blocks = _createNode('div');
602 var overlay = _createNode('div'); 603 604 /** 605 * Set ids 606 */ 607 settings_container.id = 's-cnt'; 608 settings_container_valign.id = "c-vln"; 609 settings_container_inner.id = "c-s-in"; 610 settings.id = "cs"; 611 settings_title.id = 's-ttl'; 612 settings_inner.id = 's-inr'; 613 settings_header.id = "s-hdr"; 614 settings_blocks.id = 's-bl'; 615 settings_close_btn.id = 's-c-bn'; 616 overlay.id = 'cs-ov'; 617 settings_close_btn_container.id = 's-c-bnc'; 618 settings_close_btn.className = 'c-bn'; 619 620 settings_container.setAttribute('role', 'dialog'); 621 settings_container.setAttribute('aria-modal', 'true'); 622 settings_container.setAttribute('aria-hidden', 'true'); 623 settings_container.setAttribute('aria-labelledby', 's-ttl'); 624 settings_title.setAttribute('role', 'heading'); 625 settings_container.style.visibility = overlay.style.visibility = "hidden"; 626 overlay.style.opacity = 0; 627 628 settings_close_btn_container.appendChild(settings_close_btn); 629 630 // If 'esc' key is pressed inside settings_container div => hide settings 631 _addEvent(settings_container_valign, 'keydown', function(evt){ 632 evt = evt || window.event; 633 if (evt.keyCode === 27) { 634 _cookieconsent.hideSettings(0); 635 } 636 }, true); 637 638 _addEvent(settings_close_btn, 'click', function(){ 639 _cookieconsent.hideSettings(0); 640 }); 641 }else{ 642 new_settings_blocks = _createNode('div'); 643 new_settings_blocks.id = 's-bl'; 644 } 645 646 // Add label to close button 647 settings_close_btn.setAttribute('aria-label', user_config.languages[lang]['settings_modal']['close_btn_label'] || 'Close'); 648 649 all_blocks = user_config.languages[lang]['settings_modal']['blocks']; 650 all_table_headers = user_config.languages[lang]['settings_modal']['cookie_table_headers']; 651 652 var n_blocks = all_blocks.length; 653 654 // Set settings modal title 655 settings_title.innerHTML = user_config.languages[lang]['settings_modal']['title']; 656 657 // Create settings modal content (blocks) 658 for(var i=0; i<n_blocks; ++i){ 659 660 var title_data = all_blocks[i]['title'], 661 description_data = all_blocks[i]['description'], 662 toggle_data = all_blocks[i]['toggle'], 663 cookie_table_data = all_blocks[i]['cookie_table'], 664 remove_cookie_tables = user_config['remove_cookie_tables'] === true, 665 isExpandable = (description_data && 'truthy') || (!remove_cookie_tables && (cookie_table_data && 'truthy')); 666 667 // Create title 668 var block_section = _createNode('div'); 669 var block_table_container = _createNode('div'); 670 671 // Create description 672 if(description_data){ 673 var block_desc = _createNode('div'); 674 block_desc.className = 'p'; 675 block_desc.insertAdjacentHTML('beforeend', description_data); 676 } 677 678 var block_title_container = _createNode('div'); 679 block_title_container.className = 'title'; 680 681 block_section.className = 'c-bl'; 682 block_table_container.className = 'desc'; 683 684 // Create toggle if specified (opt in/out) 685 if(typeof toggle_data !== 'undefined'){ 686 687 var accordion_id = "c-ac-"+i; 688 689 // Create button (to collapse/expand block description) 690 var block_title_btn = isExpandable ? _createNode('button') : _createNode('div'); 691 var block_switch_label = _createNode('label'); 692 var block_switch = _createNode('input'); 693 var block_switch_span = _createNode('span'); 694 var label_text_span = _createNode('span'); 695 696 // These 2 spans will contain each 2 pseudo-elements to generate 'tick' and 'x' icons 697 var block_switch_span_on_icon = _createNode('span'); 698 var block_switch_span_off_icon = _createNode('span'); 699 700 block_title_btn.className = isExpandable ? 'b-tl exp' : 'b-tl';
701 block_switch_label.className = 'b-tg'; 702 block_switch.className = 'c-tgl'; 703 block_switch_span_on_icon.className = 'on-i'; 704 block_switch_span_off_icon.className = 'off-i'; 705 block_switch_span.className = 'c-tg'; 706 label_text_span.className = "t-lb"; 707 708 if(isExpandable){ 709 block_title_btn.setAttribute('aria-expanded', 'false'); 710 block_title_btn.setAttribute('aria-controls', accordion_id); 711 } 712 713 block_switch.type = 'checkbox'; 714 block_switch_span.setAttribute('aria-hidden', 'true'); 715 716 var cookie_category = toggle_data.value; 717 block_switch.value = cookie_category; 718 719 label_text_span.textContent = title_data; 720 block_title_btn.insertAdjacentHTML('beforeend', title_data); 721 722 block_title_container.appendChild(block_title_btn); 723 block_switch_span.appendChild(block_switch_span_on_icon); 724 block_switch_span.appendChild(block_switch_span_off_icon); 725 726 /** 727 * If consent is valid => retrieve category states from cookie 728 * Otherwise use states defined in the user_config. object 729 */ 730 if(!invalid_consent){ 731 if(_inArray(saved_cookie_content['categories'], cookie_category) > -1){ 732 block_switch.checked = true; 733 !new_settings_blocks && toggle_states.push(true); 734 }else{ 735 !new_settings_blocks && toggle_states.push(false); 736 } 737 }else if(toggle_data['enabled']){ 738 block_switch.checked = true; 739 !new_settings_blocks && toggle_states.push(true); 740 741 /** 742 * Keep track of categories enabled by default (useful when mode=='opt-out') 743 */ 744 if(toggle_data['enabled']) 745 !new_settings_blocks && default_enabled_categories.push(cookie_category); 746 747 }else{ 748 !new_settings_blocks && toggle_states.push(false); 749 } 750 751 !new_settings_blocks && all_categories.push(cookie_category); 752 753 /** 754 * Set toggle as readonly if true (disable checkbox) 755 */ 756 if(toggle_data['readonly']){ 757 block_switch.disabled = true; 758 _addClass(block_switch_span, 'c-ro'); 759 !new_settings_blocks && readonly_categories.push(true); 760 }else{ 761 !new_settings_blocks && readonly_categories.push(false); 762 } 763 764 _addClass(block_table_container, 'b-acc'); 765 _addClass(block_title_container, 'b-bn'); 766 _addClass(block_section, 'b-ex'); 767 768 block_table_container.id = accordion_id; 769 block_table_container.setAttribute('aria-hidden', 'true'); 770 771 block_switch_label.appendChild(block_switch); 772 block_switch_label.appendChild(block_switch_span); 773 block_switch_label.appendChild(label_text_span); 774 block_title_container.appendChild(block_switch_label); 775 776 /** 777 * On button click handle the following :=> aria-expanded, aria-hidden and act class for current block 778 */ 779 isExpandable && (function(accordion, block_section, btn){ 780 _addEvent(block_title_btn, 'click', function(){ 781 if(!_hasClass(block_section, 'act')){ 782 _addClass(block_section, 'act'); 783 btn.setAttribute('aria-expanded', 'true'); 784 accordion.setAttribute('aria-hidden', 'false'); 785 }else{ 786 _removeClass(block_section, 'act'); 787 btn.setAttribute('aria-expanded', 'false'); 788 accordion.setAttribute('aria-hidden', 'true'); 789 } 790 }, false); 791 })(block_table_container, block_section, block_title_btn); 792 793 }else{ 794 /** 795 * If block is not a button (no toggle defined), 796 * create a simple div instead 797 */ 798 if(title_data){ 799 var block_title = _createNode('div'); 800 block_title.className = 'b-tl';
801 block_title.setAttribute('role', 'heading'); 802 block_title.setAttribute('aria-level', '3'); 803 block_title.insertAdjacentHTML('beforeend', title_data); 804 block_title_container.appendChild(block_title); 805 } 806 } 807 808 title_data && block_section.appendChild(block_title_container); 809 description_data && block_table_container.appendChild(block_desc); 810 811 // if cookie table found, generate table for this block 812 if(!remove_cookie_tables && typeof cookie_table_data !== 'undefined'){ 813 var tr_tmp_fragment = document.createDocumentFragment(); 814 815 /** 816 * Use custom table headers 817 */ 818 for(var p=0; p<all_table_headers.length; ++p){ 819 // create new header 820 var th1 = _createNode('th'); 821 var obj = all_table_headers[p]; 822 th1.setAttribute('scope', 'col'); 823 824 // get custom header content 825 if(obj){ 826 var new_column_key = obj && _getKeys(obj)[0]; 827 th1.textContent = all_table_headers[p][new_column_key]; 828 tr_tmp_fragment.appendChild(th1); 829 } 830 } 831 832 var tr_tmp = _createNode('tr'); 833 tr_tmp.appendChild(tr_tmp_fragment); 834 835 // create table header & append fragment 836 var thead = _createNode('thead'); 837 thead.appendChild(tr_tmp); 838 839 // append header to table 840 var block_table = _createNode('table'); 841 block_table.appendChild(thead); 842 843 var tbody_fragment = document.createDocumentFragment(); 844 845 // create table content 846 for(var n=0; n<cookie_table_data.length; n++){ 847 var tr = _createNode('tr'); 848 849 for(var g=0; g<all_table_headers.length; ++g){ 850 // get custom header content 851 obj = all_table_headers[g]; 852 if(obj){ 853 new_column_key = _getKeys(obj)[0]; 854 855 var td_tmp = _createNode('td'); 856 857 // Allow html inside table cells 858 td_tmp.insertAdjacentHTML('beforeend', cookie_table_data[n][new_column_key]); 859 td_tmp.setAttribute('data-column', obj[new_column_key]); 860 861 tr.appendChild(td_tmp); 862 } 863 } 864 865 tbody_fragment.appendChild(tr); 866 } 867 868 // append tbody_fragment to tbody & append the latter into the table 869 var tbody = _createNode('tbody'); 870 tbody.appendChild(tbody_fragment); 871 block_table.appendChild(tbody); 872 873 block_table_container.appendChild(block_table); 874 } 875 876 /** 877 * Append only if is either: 878 * - togglable div with title 879 * - a simple div with at least a title or description 880 */ 881 if(toggle_data && title_data || (!toggle_data && (title_data || description_data))){ 882 block_section.appendChild(block_table_container); 883 884 if(new_settings_blocks) 885 new_settings_blocks.appendChild(block_section); 886 else 887 settings_blocks.appendChild(block_section); 888 } 889 } 890 891 // Create settings buttons 892 if(!settings_buttons){ 893 settings_buttons = _createNode('div'); 894 settings_buttons.id = 's-bns'; 895 } 896 897 if(!settings_accept_all_btn){ 898 settings_accept_all_btn = _createNode('button'); 899 settings_accept_all_btn.id = 's-all-bn'; 900 settings_accept_all_btn.className ='c-bn'; 901 settings_buttons.appendChild(settings_accept_all_btn); 902 903 _addEvent(settings_accept_all_btn, 'click', function(){ 904 _cookieconsent.hideSettings(); 905 _cookieconsent.hide(); 906 _cookieconsent.accept('all'); 907 }); 908 } 909 910 settings_accept_all_btn.innerHTML = user_config.languages[lang]['settings_modal']['accept_all_btn']; 911 912 var reject_all_btn_text = user_config.languages[lang]['settings_modal']['reject_all_btn']; 913 914 // Add third [optional] reject all button if provided 915 if(reject_all_btn_text){ 916 917 if(!settings_reject_all_btn){ 918 settings_reject_all_btn = _createNode('button'); 919 settings_reject_all_btn.id = 's-rall-bn'; 920 settings_reject_all_btn.className = 'c-bn'; 921 922 _addEvent(settings_reject_all_btn, 'click', function(){ 923 _cookieconsent.hideSettings(); 924 _cookieconsent.hide(); 925 _cookieconsent.accept([]); 926 }); 927 928 settings_inner.className = "bns-t"; 929 settings_buttons.appendChild(settings_reject_all_btn); 930 } 931 932 settings_reject_all_btn.innerHTML = reject_all_btn_text; 933 } 934 935 936 if(!settings_save_btn){ 937 settings_save_btn = _createNode('button'); 938 settings_save_btn.id = 's-sv-bn'; 939 settings_save_btn.className ='c-bn'; 940 settings_buttons.appendChild(settings_save_btn); 941 942 // Add save preferences button onClick event 943 // Hide both settings modal and consent modal 944 _addEvent(settings_save_btn, 'click', function(){ 945 _cookieconsent.hideSettings(); 946 _cookieconsent.hide(); 947 _cookieconsent.accept(); 948 }); 949 } 950 951 settings_save_btn.innerHTML = user_config.languages[lang]['settings_modal']['s
951ave_settings_btn']; 952 953 954 if(new_settings_blocks) { 955 // replace entire existing cookie category blocks with the new cookie categories new blocks (in a different language) 956 settings_inner.replaceChild(new_settings_blocks, settings_blocks); 957 settings_blocks = new_settings_blocks; 958 return; 959 }; 960 961 settings_header.appendChild(settings_title); 962 settings_header.appendChild(settings_close_btn_container); 963 settings_inner.appendChild(settings_header); 964 settings_inner.appendChild(settings_blocks); 965 settings_inner.appendChild(settings_buttons); 966 settings_container_inner.appendChild(settings_inner); 967 968 settings.appendChild(settings_container_inner); 969 settings_container_valign.appendChild(settings); 970 settings_container.appendChild(settings_container_valign); 971 972 all_modals_container.appendChild(settings_container); 973 all_modals_container.appendChild(overlay); 974 } 975 976 /** 977 * Generate cookie consent html markup 978 */ 979 var _createCookieConsentHTML = function(){ 980 981 // Create main container which holds both consent modal & settings modal 982 main_container = _createNode('div'); 983 main_container.id = 'cc--main'; 984 985 // Fix layout flash 986 main_container.style.position = "fixed"; 987 main_container.style.zIndex = "2147483647"; 988 main_container.innerHTML = '<!--[if lt IE 9 ]><div id="cc_div" class="cc_div ie"></div><![endif]--><!--[if (gt IE 8)|!(IE)]><!--><div id="cc_div" class="cc_div"></div><!--<![endif]-->' 989 all_modals_container = main_container.children[0]; 990 991 // Get current language 992 var lang = _config.current_lang; 993 994 // Create consent modal 995 if(consent_modal_exists) 996 _createConsentModal(lang); 997 998 // Always create settings modal 999 _createSettingsModal(lang); 1000 1001 // Finally append everything (main_container holds both modals) 1002 (root || document.body).appendChild(main_container); 1003 } 1004 1005 /** 1006 * Update/change modals language 1007 * @param {String} lang new language 1008 * @param {Boolean} [force] update language fields forcefully 1009 * @returns {Boolean} 1010 */ 1011 _cookieconsent.updateLanguage = function(lang, force){ 1012 1013 if(typeof lang !== 'string') return; 1014 1015 /** 1016 * Validate language to avoid errors 1017 */ 1018 var new_validated_lang = _getValidatedLanguage(lang, user_config.languages); 1019 1020 /** 1021 * Set language only if it differs from current 1022 */ 1023 if(new_validated_lang !== _config.current_lang || force === true){ 1024 _config.current_lang = new_validated_lang; 1025 1026 if(consent_modal_exists){ 1027 _createConsentModal(new_validated_lang); 1028 } 1029 1030 _createSettingsModal(new_validated_lang); 1031 1032 _log("CookieConsent [LANGUAGE]: curr_lang: '" + new_validated_lang + "'"); 1033 1034 return true; 1035 } 1036 1037 return false; 1038 } 1039 1040 /** 1041 * Delete all cookies which are unused (based on selected preferences) 1042 * 1043 * @param {boolean} [clearOnFirstAction] 1044 */ 1045 var _autoclearCookies = function(clearOnFirstAction){ 1046 1047 // Get number of blocks 1048 var len = all_blocks.length; 1049 var count = -1; 1050 1051 // reset reload state 1052 reload_page = false; 1053 1054 // Retrieve all cookies 1055 var all_cookies_array = _getCookie('', 'all'); 1056 1057 // delete cookies on 'www.domain.com' and '.www.domain.com' (can also be without www) 1058 var domains = [_config.cookie_domain, '.'+_config.cookie_domain]; 1059 1060 // if domain has www, delete cookies also for 'domain.com' and '.domain.com' 1061 if(_config.cookie_domain.slice(0, 4) === 'www.'){ 1062 var non_www_domain = _config.cookie_domain.substr(4); // remove first 4 chars (www.) 1063 domains.push(non_www_domain); 1064 domains.push('.' + non_www_domain); 1065 } 1066 1067 // For each block 1068 for(var i=0; i<len; i++){ 1069 1070 // Save current block (local scope & less accesses -> ~faster value retrieval) 1071 var curr_block = all_blocks[i]; 1072 1073 // If current block has a toggle for opt in/out 1074 if(Object.prototype.hasOwnProperty.call(curr_block, "toggle")){ 1075 1076 // if current block has a cookie table, an off toggle, 1077 // and its preferences were just changed => delete cookies 1078 var category_just_disabled = _inArray(changed_settings, curr_block['toggle']['value']) > -1; 1079 if( 1080 !toggle_states[++count] && 1081 Object.prototype.hasOwnProperty.call(curr_block, "cookie_table") && 1082 (clearOnFirstAction || category_just_disabled) 1083 ){ 1084 var curr_cookie_table = curr_block['cookie_table']; 1085 1086 // Get first property name 1087 var ckey = _getKeys(all_table_headers[0])[0]; 1088 1089 // Get number of cookies defined in cookie_table 1090 var clen = curr_cookie_table.length; 1091 1092 // set "reload_page" to true if reload=on_disable 1093 if(curr_block['toggle']['reload'] === 'on_disable') 1094 category_just_disabled && (reload_page = true); 1095 1096 // for each row defined in the cookie table 1097 for(var j=0; j<clen; j++){ 1098 var curr_domains = domains; 1099 1100 // Get current row of table (corresponds to all cookie params) 1101 var curr_row = curr_cookie_table[j], found_cookies = []; 1102 var curr_cookie_name = curr_row[ckey]; 1103 var is_regex = curr_row['is_regex'] || false; 1104 var curr_cookie_domain = curr_row['domain'] || null; 1105 var curr_cookie_path = curr_row['path'] || false; 1106 1107 // set domain to the specified domain 1108 curr_cookie_domain && ( curr_domains = [curr_cookie_domain, '.'+curr_cookie_domain]); 1109 1110 // If regex provided => filter cookie array 1111 if(is_regex){ 1112 for(var n=0; n<all_cookies_array.length; n++){ 1113 if(all_cookies_array[n].match(curr_cookie_name)){ 1114 found_cookies.push(all_cookies_array[n]); 1115 } 1116 } 1117 }else{ 1118 var found_index = _inArray(all_cookies_array, curr_cookie_name); 1119 if(found_index > -1) found_cookies.push(all_cookies_array[found_index]); 1120 } 1121 1122 _log("CookieConsent [AUTOCLEAR]: search cookie: '" + curr_cookie_name + "', found:", found_cookies); 1123 1124 // If cookie exists -> delete it 1125 if(found_cookies.length > 0){ 1126 _eraseCookies(found_cookies, curr_cookie_path, curr_domains); 1127 curr_block['toggle']['reload'] === 'on_clear' && (reload_page = true); 1128 } 1129 } 1130 } 1131 } 1132 } 1133 } 1134 1135 /** 1136 * Set toggles/checkboxes based on accepted categories and save cookie 1137 * @param {string[]} accepted_categories - Array of categories to accept 1138 */ 1139 var _saveCookiePreferences = function(accepted_categories){ 1140 // (@visaoi) 1141 VisaoiCookies.allowed = [];
1142 VisaoiCookies.denied = []; 1143 1144 changed_settings = []; 1145 1146 // Retrieve all toggle/checkbox values 1147 var category_toggles = document.querySelectorAll('.c-tgl') || []; 1148 1149 // If there are opt in/out toggles ... 1150 if(category_toggles.length > 0){ 1151 1152 for(var i=0; i<category_toggles.length; i++){ 1153 if(_inArray(accepted_categories, all_categories[i]) !== -1){ 1154 VisaoiCookies.allowed.push(all_categories[i]); 1155 1156 let stack = VisaoiCookies.stack[all_categories[i]]; 1157 1158 if(stack){ 1159 for(let j=0; j<stack.length; j++){ 1160 stack[j](); 1161 } 1162 } 1163 1164 category_toggles[i].checked = true; 1165 if(!toggle_states[i]){ 1166 changed_settings.push(all_categories[i]); 1167 toggle_states[i] = true; 1168 } 1169 }else{ 1170 VisaoiCookies.denied.push(all_categories[i]); 1171 category_toggles[i].checked = false; 1172 if(toggle_states[i]){ 1173 changed_settings.push(all_categories[i]); 1174 toggle_states[i] = false; 1175 } 1176 } 1177 } 1178 } 1179 1180 /** 1181 * Clear cookies when settings/preferences change 1182 */ 1183 if(!invalid_consent && _config.autoclear_cookies && changed_settings.length > 0) 1184 _autoclearCookies(); 1185 1186 if(!consent_date) consent_date = new Date(); 1187 if(!consent_uuid) consent_uuid = _uuidv4(); 1188 1189 saved_cookie_content = { 1190 "categories": accepted_categories, 1191 "level": accepted_categories, // Copy of the `categories` property for compatibility purposes with version v2.8.0 and below. 1192 "revision": _config.revision, 1193 "data": cookie_data, 1194 "rfc_cookie": _config.use_rfc_cookie, 1195 "consent_date": consent_date.toISOString(), 1196 "consent_uuid": consent_uuid 1197 } 1198 1199 // save cookie with preferences 'categories' (only if never accepted or settings were updated) 1200 if(invalid_consent || changed_settings.length > 0){ 1201 valid_revision = true; 1202 1203 /** 1204 * Update "last_consent_update" only if it is invalid (after t) 1205 */ 1206 if(!last_consent_update) 1207 last_consent_update = consent_date; 1208 else 1209 last_consent_update = new Date(); 1210 1211 saved_cookie_content['last_consent_update'] = last_consent_update.toISOString(); 1212 1213 /** 1214 * Update accept type 1215 */ 1216 accept_type = _getAcceptType(_getCurrentCategoriesState()); 1217 1218 _setCookie(_config.cookie_name, JSON.stringify(saved_cookie_content)); 1219 _manageExistingScripts(); 1220 } 1221 1222 if(invalid_consent){ 1223 1224 /** 1225 * Delete unused/"zombie" cookies if consent is not valid (not yet expressed or cookie has expired) 1226 */ 1227 if(_config.autoclear_cookies) 1228 _autoclearCookies(true); 1229 1230 if(typeof onFirstAction === 'function') 1231 onFirstAction(_cookieconsent.getUserPreferences(), saved_cookie_content); 1232 1233 if(typeof onAccept === 'function') 1234 onAccept(saved_cookie_content); 1235 1236 /** 1237 * Set consent as valid 1238 */ 1239 invalid_consent = false; 1240 1241 if(_config.mode === 'opt-in') return; 1242 } 1243 1244 // fire onChange only if settings were changed 1245 if(typeof onChange === "function" && changed_settings.length > 0) 1246 onChange(saved_cookie_content, changed_settings); 1247 1248 /** 1249 * reload page if needed 1250 */ 1251 _deleteDeniedCookies(); 1252 1253 if(reload_page) 1254 window.location.reload(); 1255 } 1256 1257 /** 1258 * Returns index of found element inside array, otherwise -1 1259 * @param {Array} arr 1260 * @param {Object} value 1261 * @returns {number} 1262 */ 1263 var _inArray = function(arr, value){ 1264 return arr.indexOf(value); 1265 } 1266 1267 /** 1268 * Helper function which prints info (console.log()) 1269 * @param {Object} print_msg 1270 * @param {Object} [optional_param] 1271 */ 1272 var _log = function(print_msg, optional_param, error) { 1273 if (ENABLE_LOGS) { 1274 !error ? 1275 console.log(print_msg, optional_param !== undefined ? optional_param : ' ') : 1276 console.error(print_msg, optional_param || ""); 1277 } 1278 } 1279 1280 /** 1281 * Helper function which creates an HTMLElement object based on 'type' and returns it. 1282 * @param {string} type 1283 * @returns {HTMLElement} 1284 */ 1285 var _createNode = function(type){ 1286 var el = document.createElement(type); 1287 if(type === 'button'){ 1288 el.setAttribute('type', type); 1289 } 1290 return el; 1291 } 1292 1293 /** 1294 * Generate RFC4122-compliant UUIDs. 1295 * https://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid?page=1&tab=votes#tab-top 1296 * @returns {string} 1297 */ 1298 var _uuidv4 = function(){ 1299 return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, function(c){ 1300 try{ 1301 return (c ^ (window.crypto || window.msCrypto).getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) 1302 }catch(e){ 1303 return ''; 1304 } 1305 }); 1306 } 1307 1308 /** 1309 * Resolve which language should be used. 1310 * 1311 * @param {Object} languages Object with language translations 1312 * @param {string} [requested_language] Language specified by given configuration parameters 1313 * @returns {string} 1314 */ 1315 var _resolveCurrentLang = function (languages, requested_language) { 1316 1317 if (_config.auto_language === 'browser') { 1318 return _getValidatedLanguage(_getBrowserLang(), languages); 1319 } else if (_config.auto_language === 'document') { 1320 return _getValidatedLanguage(document.documentElement.lang, languages); 1321 } else { 1322 if (typeof requested_language === 'string') { 1323 return _config.current_lang = _getValidatedLanguage(requested_language, languages); 1324 } 1325 } 1326 1327 _log("CookieConsent [LANG]: setting current_lang = '" + _config.current_lang + "'"); 1328 return _config.current_lang; // otherwise return default 1329 } 1330 1331 /** 1332 * Get current client's browser language 1333 * @returns {string} 1334 */ 1335 var _getBrowserLang = function(){ 1336 var browser_lang = navigator.language || navigator.browserLanguage; 1337 browser_lang.length > 2 && (browser_lang = browser_lang[0]+browser_lang[1]); 1338 _log("CookieConsent [LANG]: detected_browser_lang = '"+ browser_lang + "'"); 1339 return browser_lang.toLowerCase() 1340 } 1341 1342 /** 1343 * Trap focus inside modal and focus the first 1344 * focusable element of current active modal 1345 */ 1346 var _handleFocusTrap = function(){ 1347 var tabbedOutsideDiv = false;
1348 var tabbedInsideModal = false; 1349 1350 _addEvent(document, 'keydown', function(e){ 1351 e = e || window.event; 1352 1353 // If is tab key => ok 1354 if(e.key !== 'Tab') return; 1355 1356 // If there is any modal to focus 1357 if(current_modal_focusable){ 1358 // If reached natural end of the tab sequence => restart 1359 if(e.shiftKey){ 1360 if (document.activeElement === current_modal_focusable[0]) { 1361 current_modal_focusable[1].focus(); 1362 e.preventDefault(); 1363 } 1364 }else{ 1365 if (document.activeElement === current_modal_focusable[1]) { 1366 current_modal_focusable[0].focus(); 1367 e.preventDefault(); 1368 } 1369 } 1370 1371 // If have not yet used tab (or shift+tab) and modal is open ... 1372 // Focus the first focusable element 1373 if(!tabbedInsideModal && !clicked_inside_modal){ 1374 tabbedInsideModal = true; 1375 !tabbedOutsideDiv && e.preventDefault(); 1376 1377 if(e.shiftKey){ 1378 if(current_modal_focusable[3]){ 1379 if(!current_modal_focusable[2]){ 1380 current_modal_focusable[0].focus(); 1381 }else{ 1382 current_modal_focusable[2].focus(); 1383 } 1384 }else{ 1385 current_modal_focusable[1].focus(); 1386 } 1387 }else{ 1388 if(current_modal_focusable[3]){ 1389 current_modal_focusable[3].focus(); 1390 }else{ 1391 current_modal_focusable[0].focus(); 1392 } 1393 } 1394 } 1395 } 1396 1397 !tabbedInsideModal && (tabbedOutsideDiv = true); 1398 }); 1399 1400 if(document.contains){ 1401 _addEvent(main_container, 'click', function(e){ 1402 e = e || window.event; 1403 /** 1404 * If click is on the foreground overlay (and not inside settings_modal), 1405 * hide settings modal 1406 * 1407 * Notice: click on div is not supported in IE 1408 */ 1409 if(settings_modal_visible){ 1410 if(!settings_inner.contains(e.target)){ 1411 _cookieconsent.hideSettings(0); 1412 clicked_inside_modal = false; 1413 }else{ 1414 clicked_inside_modal = true; 1415 } 1416 }else if(consent_modal_visible){ 1417 if(consent_modal.contains(e.target)){ 1418 clicked_inside_modal = true; 1419 } 1420 } 1421 1422 }, true); 1423 } 1424 } 1425 1426 /** 1427 * (@visaoi) 1428 * Helper function which deletes cookies which its categories is in VisaoiCookie.denied 1429 */ 1430 var _deleteDeniedCookies = () => { 1431 console.log("Hora de comer!"); 1432 // delete cookies which its categories is in VisaoiCookie.denied (@visaoi) 1433 let blocks = user_config.languages.en.settings_modal.blocks; 1434 for (let x = 0; x < blocks.length; x++) { 1435 if ( 1436 blocks[x].cookie_table && 1437 blocks[x].toggle 1438 ) { 1439 console.log("Quero biscoitos de sabor '" + blocks[x].toggle.value + "'"); 1440 let cookies = blocks[x].cookie_table; 1441 1442 //get list of cookies to delete with regex 1443 let allCookieNames = document.cookie.split(';'); 1444 allCookieNames = allCookieNames.map(cookie => cookie 1445 .split('=')[0] 1446 .replace(/\s+/g, '')); 1447 1448 console.log("All cookies: ", allCookieNames); 1449 1450 for (let y = 0; y < cookies.length; y++) { 1451 if (VisaoiCookies.denied.includes(blocks[x].toggle.value)) { 1452 //delete blocks[x].cookie_table.col1 from blocks[x].cookie_table;
1453 if (cookies[y].regex) { 1454 let cookies_to_delete = allCookieNames.filter(cookie => { 1455 const regex =new RegExp(cookies[y].col1.replace(/\*$/g, '[A-Za-z0-9\\!\\#\\$\\%\\&\\\'\\*\\+\\-\\.\\^_\\`\\|\\~]*'),'g'); 1456 1457 return regex.test(cookie); 1458 }); 1459 1460 console.log(cookies[y].col1, ">",cookies[y].col1.replace(/\*$/g, '[A-Za-z0-9\\!\\#\\$\\%\\&\\\'\\*\\+\\-\\.\\^_\\`\\|\\~]*')); 1461 console.log("Cookies to delete: ", cookies_to_delete); 1462 _eraseCookies(cookies_to_delete); 1463 } else { 1464 console.log("Deletando",cookies[y]); 1465 _eraseCookies([cookies[y].col1]); 1466 } 1467 } 1468 } 1469 } 1470 } 1471 } 1472 1473 /** 1474 * Manage each modal's layout 1475 * @param {Object} gui_options 1476 */ 1477 var _guiManager = function(gui_options, only_consent_modal){ 1478 1479 // If gui_options is not object => exit 1480 if(typeof gui_options !== 'object') return; 1481 1482 var consent_modal_options = gui_options['consent_modal']; 1483 var settings_modal_options = gui_options['settings_modal']; 1484 1485 /** 1486 * Helper function which adds layout and 1487 * position classes to given modal 1488 * 1489 * @param {HTMLElement} modal 1490 * @param {string[]} allowed_layouts 1491 * @param {string[]} allowed_positions 1492 * @param {string} layout 1493 * @param {string[]} position 1494 */ 1495 function _setLayout(modal, allowed_layouts, allowed_positions, allowed_transitions, layout, position, transition){ 1496 position = (position && position.split(" ")) || []; 1497 1498 // Check if specified layout is valid 1499 if(_inArray(allowed_layouts, layout) > -1){ 1500 1501 // Add layout classes 1502 _addClass(modal, layout); 1503 1504 // Add position class (if specified) 1505 if(!(layout === 'bar' && position[0] === 'middle') && _inArray(allowed_positions, position[0]) > -1){ 1506 for(var i=0; i<position.length; i++){ 1507 _addClass(modal, position[i]); 1508 } 1509 } 1510 } 1511 1512 // Add transition class 1513 (_inArray(allowed_transitions, transition) > -1) && _addClass(modal, transition); 1514 } 1515 1516 if(consent_modal_exists && consent_modal_options){ 1517 _setLayout( 1518 consent_modal, 1519 ['box', 'bar', 'cloud'], 1520 ['top', 'middle', 'bottom'], 1521 ['zoom', 'slide'], 1522 consent_modal_options['layout'], 1523 consent_modal_options['position'], 1524 consent_modal_options['transition'] 1525 ); 1526 } 1527 1528 if(!only_consent_modal && settings_modal_options){ 1529 _setLayout( 1530 settings_container, 1531 ['bar'], 1532 ['left', 'right'], 1533 ['zoom', 'slide'], 1534 settings_modal_options['layout'], 1535 settings_modal_options['position'], 1536 settings_modal_options['transition'] 1537 ); 1538 } 1539 } 1540 1541 /** 1542 * Returns true if cookie category is accepted by the user 1543 * @param {string} cookie_category 1544 * @returns {boolean} 1545 */ 1546 _cookieconsent.allowedCategory = function(cookie_category){ 1547 1548 if(!invalid_consent || _config.mode === 'opt-in') 1549 var allowed_categories = JSON.parse(_getCookie(_config.cookie_name, 'one', true) || '{}')['categories'] || [] 1550 else // mode is 'opt-out' 1551 var allowed_categories = default_enabled_categories; 1552 1553 return _inArray(allowed_categories, cookie_category) > -1; 1554 } 1555 1556 /** 1557 * "Init" method. Will run once and only if modals do not exist 1558 * 1559 * @param {{ 1560 * page_scripts: boolean, 1561 * gui_options: Object, 1562 * languages: { 1563 * "en": { 1564 * consent_modal: Object, 1565 * settings_modal: { 1566 * blocks: Array<{ 1567 * toggle?: {value:string}, 1568 * cookie_table?: Array<{ 1569 * col1: string, //nome 1570 * col2: string, //dominio 1571 * col3: string, //expiracao 1572 * col4: string, //descricao 1573 * regex: boolean 1574 * }> 1575 * }>, 1576 * } 1577 * } 1578 * } 1579 * }} user_config 1580 */ 1581 _cookieconsent.run = function(user_config, bypass=false, isSubdomain=false) { 1582 //or is www 1583 subdomain = isSubdomain || window.location.hostname.split('.')[0] === 'www'; 1584 1585 // Ignora o consentimento e executa todos os scripts 1586 if (bypass) { 1587 document.querySelectorAll('script[data-src]').forEach(function (script) { 1588 var src = script.getAttribute('data-src'); 1589 script.setAttribute('src', src); 1590 script.removeAttribute('data-src'); 1591 }); 1592 return; 1593 } 1594 1595 if(!document.getElementById('cc_div')){ 1596 1597 // configure all parameters 1598 _setConfig(user_config); 1599 1600 // if is bot, don't run plugin 1601 if(is_bot) return; 1602 1603 // Retrieve cookie value (if set) 1604 saved_cookie_content = JSON.parse(_getCookie(_config.cookie_name, 'one', true) || "{}"); 1605 1606 // Retrieve "consent_uuid" 1607 consent_uuid = saved_cookie_content['consent_uuid']; 1608 1609 // If "consent_uuid" is present => assume that consent was previously given 1610 var cookie_consent_accepted = consent_uuid !== undefined; 1611 1612 // Retrieve "consent_date" 1613 consent_date = saved_cookie_content['consent_date']; 1614 consent_date && (consent_date = new Date(consent_date)); 1615 1616 // Retrieve "last_consent_update" 1617 last_consent_update = saved_cookie_content['last_consent_update']; 1618 last_consent_update && (last_consent_update = new Date(last_consent_update)); 1619 1620 // Retrieve "data" 1621 cookie_data = saved_cookie_content['data'] !== undefined ? saved_cookie_content['data'] : null; 1622 1623 // If revision is enabled and current value !== saved value inside the cookie =>
1623 revision is not valid 1624 if(revision_enabled && saved_cookie_content['revision'] !== _config.revision){ 1625 valid_revision = false; 1626 } 1627 1628 // If consent is not valid => create consent modal 1629 consent_modal_exists = invalid_consent = (!cookie_consent_accepted || !valid_revision || !consent_date || !last_consent_update || !consent_uuid); 1630 1631 //merge saved_cookie_content["categories"] with VisaoiCookie.allowed 1632 VisaoiCookies.allowed = [...VisaoiCookies.allowed, ...(saved_cookie_content["categories"] || [])] || []; 1633 VisaoiCookies.allowed = VisaoiCookies.allowed.filter(function (item, pos) { 1634 return VisaoiCookies.allowed.indexOf(item) === pos; 1635 }); 1636 1637 //denied coolies are every category except allowed 1638 user_config.languages["en"].settings_modal.blocks.forEach(block => { 1639 if (block.toggle) { 1640 //if array has item 1641 if (!VisaoiCookies.allowed.includes(block.toggle.value)) { 1642 VisaoiCookies.denied.push(block.toggle.value); 1643 } 1644 } 1645 }) 1646 1647 _deleteDeniedCookies(); 1648 1649 // Generate cookie-settings dom (& consent modal) 1650 _createCookieConsentHTML(); 1651 1652 _getModalFocusableData(); 1653 _guiManager(user_config['gui_options']); 1654 _addDataButtonListeners(); 1655 1656 if(_config.autorun && consent_modal_exists){ 1657 _cookieconsent.show(user_config['delay'] || 0); 1658 } 1659 1660 // Add class to enable animations/transitions 1661 setTimeout(function(){_addClass(main_container, 'c--anim');}, 30); 1662 1663 // Accessibility :=> if tab pressed => trap focus inside modal 1664 setTimeout(function(){_handleFocusTrap();}, 100); 1665 1666 // If consent is valid 1667 if(!invalid_consent){ 1668 var rfc_prop_exists = typeof saved_cookie_content['rfc_cookie'] === "boolean"; 1669 1670 /* 1671 * Convert cookie to rfc format (if `use_rfc_cookie` is enabled) 1672 */ 1673 if(!rfc_prop_exists || (rfc_prop_exists && saved_cookie_content['rfc_cookie'] !== _config.use_rfc_cookie)){ 1674 saved_cookie_content['rfc_cookie'] = _config.use_rfc_cookie; 1675 _setCookie(_config.cookie_name, JSON.stringify(saved_cookie_content)); 1676 } 1677 1678 /** 1679 * Update accept type 1680 */ 1681 accept_type = _getAcceptType(_getCurrentCategoriesState()); 1682 1683 _manageExistingScripts(); 1684 1685 if(typeof onAccept === 'function') 1686 onAccept(saved_cookie_content); 1687 1688 _log("CookieConsent [NOTICE]: consent already given!", saved_cookie_content); 1689 1690 }else{ 1691 if(_config.mode === 'opt-out'){ 1692 _log("CookieConsent [CONFIG] mode='" + _config.mode + "', default enabled categories:", default_enabled_categories); 1693 _manageExistingScripts(default_enabled_categories); 1694 } 1695 _log("CookieConsent [NOTICE]: ask for consent!"); 1696 } 1697 }else{ 1698 _log("CookieConsent [NOTICE]: cookie consent already attached to body!"); 1699 } 1700 } 1701 1702 /** 1703 * Show settings modal (with optional delay) 1704 * @param {number} delay 1705 */ 1706 _cookieconsent.showSettings = function(delay){ 1707 setTimeout(function() { 1708 _addClass(html_dom, "show--settings"); 1709 settings_container.setAttribute('aria-hidden', 'false'); 1710 document.getElementById("c-vln").style.backdropFilter = "blur(10px)"; 1711 document.getElementsByTagName("html")[0].style.overflow = "hidden"; 1712 settings_modal_visible = true; 1713 1714 /** 1715 * Set focus to the first focusable element inside settings modal 1716 */ 1717 setTimeout(function(){ 1718 // If there is no consent-modal, keep track of the last focused elem. 1719 if(!consent_modal_visible){ 1720 last_elem_before_modal = document.activeElement; 1721 }else{ 1722 last_consent_modal_btn_focus = document.activeElement; 1723 } 1724 1725 if (settings_modal_focusable.length === 0) return; 1726 1727 if(settings_modal_focusable[3]){ 1728 settings_modal_focusable[3].focus(); 1729 }else{ 1730 settings_modal_focusable[0].focus(); 1731 } 1732 current_modal_focusable = settings_modal_focusable; 1733 }, 200); 1734 1735 _log("CookieConsent [SETTINGS]: show settings_modal"); 1736 }, delay > 0 ? delay : 0); 1737 } 1738 1739 /** 1740 * This function handles the loading/activation logic of the already 1741 * existing scripts based on the current accepted cookie categories 1742 * 1743 * @param {string[]} [must_enable_categories] 1744 */ 1745 var _manageExistingScripts = function(must_enable_categories){ 1746 1747 if(!_config.page_scripts) return; 1748 1749 // get all the scripts with "cookie-category" attribute 1750 var scripts = document.querySelectorAll('script[' + _config.script_selector + ']'); 1751 var accepted_categories = must_enable_categories || saved_cookie_content['categories'] || []; 1752 1753 /** 1754 * Load scripts (sequentially), using a recursive function 1755 * which loops through the scripts array 1756 * @param {Element[]} scripts scripts to load 1757 * @param {number} index current script to load 1758 */ 1759 var _loadScripts = function(scripts, index){ 1760 if(index < scripts.length){ 1761 1762 var curr_script = scripts[index]; 1763 var curr_script_category = curr_script.getAttribute(_config.script_selector); 1764 1765 /** 1766 * If current script's category is on the array of categories 1767 * accepted by the user => load script 1768 */ 1769 if(_inArray(accepted_categories, curr_script_category) > -1){ 1770 1771 curr_script.type = 'text/javascript'; 1772 curr_script.removeAttribute(_config.script_selector); 1773 1774 // get current script data-src 1775 var src = curr_script.getAttribute('data-src'); 1776 1777 // some scripts (like ga) might throw warning if data-src is present 1778 src && curr_script.removeAttribute('data-src'); 1779 1780 // create fresh script (with the same code) 1781 var fresh_script = _createNode('script'); 1782 fresh_script.textContent = curr_script.innerHTML; 1783 1784 // Copy attributes over to the new "revived" script 1785 (function(destination, source){ 1786 var attributes = source.attributes; 1787 var len = attributes.length; 1788 for(var i=0; i<len; i++){ 1789 var attr_name = attributes[i].nodeName; 1790 destination.setAttribute(attr_name , source[attr_name] || source.getAttribute(attr_name)); 1791 } 1792 })(fresh_script, curr_script); 1793 1794 // set src (if data-src found) 1795 src ? (fresh_script.src = src) : (src = curr_script.src); 1796 1797 // if script has "src" attribute 1798 // try loading it sequentially 1799 if(src){ 1800 // load script sequentially => the next script will not be loaded 1801 // until the current's script onload event triggers 1802 if(fresh_script.readyState) { // only required for IE <9 1803 fresh_script.onreadystatechange = function() { 1804 if (fresh_script.readyState === "loaded" || fresh_script.readyState === "complete" ) { 1805 fresh_script.onreadystatechange = null; 1806 _loadScripts(scripts, ++index); 1807 } 1808 }; 1809 }else{ // others 1810 fresh_script.onload = function(){ 1811 fresh_script.onload = null; 1812 _loadScripts(scripts, ++index); 1813 }; 1814 } 1815 } 1816 1817 // Replace current "sleeping" script with the new "revived" one 1818 curr_script.parentNode.replaceChild(fresh_script, curr_script); 1819 1820 /** 1821 * If we managed to get here and scr is still set, it means that 1822 * the script is loading/loaded sequentially so don't go any further 1823 */ 1824 if(src) return; 1825 } 1826 1827 // Go to next script right away 1828 _loadScripts(scripts, ++index); 1829 } 1830 } 1831 1832 _loadScripts(scripts, 0); 1833 } 1834 1835 /** 1836 * Save custom data inside cookie 1837 * @param {object|string} new_data 1838 * @param {string} [mode] 1839 * @returns {boolean} 1840 */
1841 var _setCookieData = function(new_data, mode){ 1842 1843 var set = false; 1844 /** 1845 * If mode is 'update': 1846 * add/update only the specified props. 1847 */ 1848 if(mode === 'update'){ 1849 cookie_data = _cookieconsent.get('data'); 1850 var same_type = typeof cookie_data === typeof new_data; 1851 1852 if(same_type && typeof cookie_data === "object"){ 1853 !cookie_data && (cookie_data = {}); 1854 1855 for(var prop in new_data){ 1856 if(cookie_data[prop] !== new_data[prop]){ 1857 cookie_data[prop] = new_data[prop] 1858 set = true; 1859 } 1860 } 1861 }else if((same_type || !cookie_data) && cookie_data !== new_data){ 1862 cookie_data = new_data; 1863 set = true; 1864 } 1865 }else{ 1866 cookie_data = new_data; 1867 set = true; 1868 } 1869 1870 if(set){ 1871 saved_cookie_content['data'] = cookie_data; 1872 _setCookie(_config.cookie_name, JSON.stringify(saved_cookie_content)); 1873 } 1874 1875 return set; 1876 } 1877 1878 /** 1879 * Helper method to set a variety of fields 1880 * @param {string} field 1881 * @param {object} data 1882 * @returns {boolean} 1883 */ 1884 _cookieconsent.set = function(field, data){ 1885 switch(field){ 1886 case 'data': return _setCookieData(data['value'], data['mode']); 1887 default: return false; 1888 } 1889 } 1890 1891 /** 1892 * Retrieve data from existing cookie 1893 * @param {string} field 1894 * @param {string} [cookie_name] 1895 * @returns {any} 1896 */ 1897 _cookieconsent.get = function(field, cookie_name){ 1898 var cookie = JSON.parse(_getCookie(cookie_name || _config.cookie_name, 'one', true) || "{}"); 1899 1900 return cookie[field]; 1901 } 1902 1903 /** 1904 * Read current configuration value 1905 * @returns {any} 1906 */ 1907 _cookieconsent.getConfig = function(field){ 1908 return _config[field] || user_config[field]; 1909 } 1910 1911 /** 1912 * Obtain accepted and rejected categories 1913 * @returns {{accepted: string[], rejected: string[]}} 1914 */ 1915 var _getCurrentCategoriesState = function(){ 1916 1917 // get accepted categories 1918 accepted_categories = saved_cookie_content['categories'] || []; 1919 1920 // calculate rejected categories (all_categories - accepted_categories) 1921 rejected_categories = all_categories.filter(function(category){ 1922 return (_inArray(accepted_categories, category) === -1); 1923 }); 1924 1925 return { 1926 accepted: accepted_categories, 1927 rejected: rejected_categories 1928 } 1929 } 1930 1931 /** 1932 * Calculate "accept type" given current categories state 1933 * @param {{accepted: string[], rejected: string[]}} currentCategoriesState 1934 * @returns {string} 1935 */ 1936 var _getAcceptType = function(currentCategoriesState){ 1937 1938 var type = 'custom'; 1939 1940 // number of categories marked as necessary/readonly 1941 var necessary_categories_length = readonly_categories.filter(function(readonly){ 1942 return readonly === true; 1943 }).length; 1944 1945 // calculate accept type based on accepted/rejected categories 1946 if(currentCategoriesState.accepted.length === all_categories.length) 1947 type = 'all'; 1948 else if(currentCategoriesState.accepted.length === necessary_categories_length) 1949 type = 'necessary' 1950 1951 return type; 1952 } 1953 1954 /** 1955 * @typedef {object} userPreferences 1956 * @property {string} accept_type 1957 * @property {string[]} accepted_categories 1958 * @property {string[]} rejected_categories 1959 */ 1960 1961 /** 1962 * Retrieve current user preferences (summary) 1963 * @returns {userPreferences} 1964 */ 1965 _cookieconsent.getUserPreferences = function(){ 1966 var currentCategoriesState = _getCurrentCategoriesState(); 1967 var accept_type = _getAcceptType(currentCategoriesState); 1968 1969 return { 1970 'accept_type': accept_type, 1971 'accepted_categories': currentCategoriesState.accepted, 1972 'rejected_categories': currentCategoriesState.rejected 1973 } 1974 } 1975 1976 /** 1977 * Function which will run after script load 1978 * @callback scriptLoaded 1979 */ 1980 1981 /** 1982 * Dynamically load script (append to head) 1983 * @param {string} src 1984 * @param {scriptLoaded} callback 1985 * @param {object[]} [attrs] Custom attributes 1986 */ 1987 _cookieconsent.loadScript = function(src, callback, attrs){ 1988 1989 var function_defined = typeof callback === 'function'; 1990 1991 // Load script only if not already loaded 1992 if(!document.querySelector('script[src="' + src + '"]')){ 1993 1994 var script = _createNode('script'); 1995 1996 // if an array is provided => add custom attributes 1997 if(attrs && attrs.length > 0){ 1998 for(var i=0; i<attrs.length; ++i){ 1999 attrs[i] && script.setAttribute(attrs[i]['name'], attrs[i]['value']); 2000 } 2001 } 2002 2003 // if callback function defined => run callback onload 2004 if(function_defined){ 2005 script.onload = callback; 2006 } 2007 2008 script.src = src; 2009 2010 /** 2011 * Append script to head 2012 */ 2013 document.head.appendChild(script); 2014 } else { 2015 function_defined && callback(); 2016 } 2017 2018 /** 2019 * check if "cc_cookie" cookie exists 2020 */ 2021 /*if(_getCookie(_config.cookie_name, 'one', true)) { 2022 /** 2023 * manage iframes 2024 * / 2025 document.querySelectorAll('iframe[data-src]').forEach(function(iframe) { 2026 //if cookie category is accepted... 2027 if (_inArray(accepted_categories, iframe.getAttribute('data-category')) !== -1) { 2028 iframe.src = iframe.getAttribute('data-src'); 2029 } 2030 }); 2031 }*/ 2032 } 2033 2034 /** 2035 * Manage dynamically loaded scripts: https://github.com/orestbida/cookieconsent/issues/101 2036 * If plugin has already run, call this method to enable 2037 * the newly added scripts based on currently selected preferences 2038 */ 2039 _cookieconsent.updateScripts = function(){ 2040 _manageExistingScripts(); 2041 } 2042 2043 /** 2044 * Show cookie consent modal (with delay parameter) 2045 * @param {number} [delay] 2046 * @param {boolean} [create_modal] create modal if it doesn't exist 2047 */ 2048 _cookieconsent.show = function(delay, create_modal){ 2049 2050 if(create_modal === true) 2051 _createConsentModal(_config.current_lang); 2052 2053 if(consent_modal_exists){ 2054 setTimeout(function() { 2055 _addClass(html_dom, "show--consent"); 2056 2057 /** 2058 * Update attributes/internal statuses 2059 */ 2060 consent_modal.setAttribute('aria-hidden', 'false'); 2061 consent_modal_visible = true; 2062 2063 setTimeout(function(){ 2064 last_elem_before_modal = document.activeElement; 2065 current_modal_focusable = consent_modal_focusable; 2066 }, 200); 2067 2068 _log("CookieConsent [MODAL]: show consent_modal"); 2069 }, delay > 0 ? delay : (create_modal ? 30 : 0)); 2070 } 2071 } 2072 2073 /** 2074 * Hide consent modal 2075 */ 2076 _cookieconsent.hide = function(){ 2077 if(consent_modal_exists){ 2078 _removeClass(html_dom, "show--consent"); 2079 consent_modal.setAttribute('aria-hidden', 'true'); 2080 consent_modal_visible = false;
2081 2082 setTimeout(function(){ 2083 //restore focus to the last page element which had focus before modal opening 2084 last_elem_before_modal.focus(); 2085 current_modal_focusable = null; 2086 }, 200); 2087 2088 _log("CookieConsent [MODAL]: hide"); 2089 } 2090 } 2091 2092 /** 2093 * Hide settings modal 2094 */ 2095 _cookieconsent.hideSettings = function(){ 2096 _removeClass(html_dom, "show--settings"); 2097 settings_modal_visible = false; 2098 document.getElementById("c-vln").style.backdropFilter = "unset"; 2099 settings_container.setAttribute('aria-hidden', 'true'); 2100 document.getElementsByTagName("html")[0].style.overflow = ""; 2101 2102 2103 setTimeout(function(){ 2104 /** 2105 * If consent modal is visible, focus him (instead of page document) 2106 */ 2107 if(consent_modal_visible){ 2108 last_consent_modal_btn_focus && last_consent_modal_btn_focus.focus(); 2109 current_modal_focusable = consent_modal_focusable; 2110 }else{ 2111 /** 2112 * Restore focus to last page element which had focus before modal opening 2113 */ 2114 last_elem_before_modal && last_elem_before_modal.focus(); 2115 current_modal_focusable = null; 2116 } 2117 2118 clicked_inside_modal = false; 2119 }, 200); 2120 2121 _log("CookieConsent [SETTINGS]: hide settings_modal"); 2122 } 2123 2124 /** 2125 * Accept cookieconsent function API 2126 * @param {string[]|string} _categories - Categories to accept 2127 * @param {string[]} [_exclusions] - Excluded categories [optional] 2128 */ 2129 _cookieconsent.accept = function(_categories, _exclusions){ 2130 var categories = _categories || undefined; 2131 var exclusions = _exclusions || []; 2132 var to_accept = []; 2133 2134 /** 2135 * Get all accepted categories 2136 * @returns {string[]} 2137 */ 2138 var _getCurrentPreferences = function(){ 2139 var toggles = document.querySelectorAll('.c-tgl') || []; 2140 var states = []; 2141 2142 for(var i=0; i<toggles.length; i++){ 2143 if(toggles[i].checked){ 2144 states.push(toggles[i].value); 2145 } 2146 } 2147 return states; 2148 } 2149 2150 if(!categories){ 2151 to_accept = _getCurrentPreferences(); 2152 }else{ 2153 if( 2154 typeof categories === "object" && 2155 typeof categories.length === "number" 2156 ){ 2157 for(var i=0; i<categories.length; i++){ 2158 if(_inArray(all_categories, categories[i]) !== -1) { 2159 to_accept.push(categories[i]); 2160 } 2161 2162 } 2163 }else if(typeof categories === "string"){ 2164 if(categories === 'all') 2165 to_accept = all_categories.slice(); 2166 else{ 2167 if(_inArray(all_categories, categories) !== -1) 2168 to_accept.push(categories); 2169 } 2170 } 2171 } 2172 2173 // Remove excluded categories 2174 if(exclusions.length >= 1){ 2175 for(i=0; i<exclusions.length; i++){ 2176 to_accept = to_accept.filter(function(item) { 2177 return item !== exclusions[i] 2178 }) 2179 } 2180 } 2181 2182 // Add back all the categories set as "readonly/required" 2183 for(i=0; i<all_categories.length; i++){ 2184 if( 2185 readonly_categories[i] === true && 2186 _inArray(to_accept, all_categories[i]) === -1 2187 ){ 2188 to_accept.push(all_categories[i]); 2189 } 2190 } 2191 2192 _saveCookiePreferences(to_accept); 2193 } 2194 2195 /** 2196 * API function to easily erase cookies 2197 * @param {(string|string[])} _cookies 2198 * @param {string} [_path] - optional 2199 * @param {string} [_domain] - optional 2200 */
2201 _cookieconsent.eraseCookies = function(_cookies, _path, _domain){ 2202 var cookies = []; 2203 var domains = _domain 2204 ? [_domain, "."+_domain] 2205 : [_config.cookie_domain, "."+_config.cookie_domain]; 2206 2207 if(typeof _cookies === "object" && _cookies.length > 0){ 2208 for(var i=0; i<_cookies.length; i++){ 2209 this.validCookie(_cookies[i]) && cookies.push(_cookies[i]); 2210 } 2211 }else{ 2212 this.validCookie(_cookies) && cookies.push(_cookies); 2213 } 2214 2215 _eraseCookies(cookies, _path, domains); 2216 } 2217 2218 /** 2219 * Set cookie, by specifying name and value 2220 * @param {string} name 2221 * @param {string} value 2222 */ 2223 var _setCookie = function(name, value) { 2224 2225 var cookie_expiration = _config.cookie_expiration; 2226 2227 if(typeof _config.cookie_necessary_only_expiration === 'number' && accept_type === 'necessary') 2228 cookie_expiration = _config.cookie_necessary_only_expiration; 2229 2230 value = _config.use_rfc_cookie ? encodeURIComponent(value) : value; 2231 2232 var date = new Date(); 2233 date.setTime(date.getTime() + (1000 * (cookie_expiration * 24 * 60 * 60))); 2234 var expires = "; expires=" + date.toUTCString(); 2235 2236 var cookieStr = name + "=" + (value || "") + expires + "; Path=" + _config.cookie_path + ";"; 2237 cookieStr += " SameSite=" + _config.cookie_same_site + ";"; 2238 2239 // assures cookie works with localhost (=> don't specify domain if on localhost) 2240 if(window.location.hostname.indexOf(".") > -1){ 2241 cookieStr += " Domain=" + _config.cookie_domain + ";"; 2242 } 2243 2244 if(window.location.protocol === "https:") { 2245 cookieStr += " Secure;"; 2246 } 2247 2248 document.cookie = cookieStr; 2249 2250 _log("CookieConsent [SET_COOKIE]: '" + name + "' expires after " + cookie_expiration + " day(s)"); 2251 } 2252 2253 /** 2254 * Get cookie value by name, 2255 * returns the cookie value if found (or an array 2256 * of cookies if filter provided), otherwise empty string: "" 2257 * @param {string} name 2258 * @param {string} filter 'one' or 'all' 2259 * @param {boolean} [get_value] set to true to obtain its value 2260 * @returns {string|string[]} 2261 */ 2262 var _getCookie = function(name, filter, get_value) { 2263 var found; 2264 2265 if(filter === 'one'){ 2266 found = document.cookie.match("(^|;)\\s*" + name + "\\s*=\\s*([^;]+)"); 2267 found = found ? (get_value ? found.pop() : name) : ""; 2268 2269 if(found && name === _config.cookie_name){ 2270 try{ 2271 found = JSON.parse(found) 2272 }catch(e){ 2273 try { 2274 found = JSON.parse(decodeURIComponent(found)) 2275 } catch (e) { 2276 // if I got here => cookie value is not a valid json string 2277 found = {}; 2278 } 2279 } 2280 found = JSON.stringify(found); 2281 } 2282 }else if(filter === 'all'){ 2283 // array of names of all existing cookies 2284 var cookies = document.cookie.split(/;\s*/); found = []; 2285 for(var i=0; i<cookies.length; i++){ 2286 found.push(cookies[i].split("=")[0]); 2287 } 2288 } 2289 2290 return found; 2291 } 2292 2293 /** 2294 * Delete cookie by name & path 2295 * @param {string[]} cookies 2296 * @param {string} [custom_path] - optional 2297 * @param {string[]} domains - example: ['domain.com', '.domain.com'] 2298 */ 2299 var _eraseCookies = function(cookies, custom_path, domains) { 2300 domains = [ 2301 window.location.hostname 2302 ]; 2303 2304 if (subdomain) { 2305 let parent = window.location.hostname.split('.'); 2306 parent.shift(); 2307 domains.push('.'+parent.join('.')); 2308 } 2309 2310 var path = custom_path ? custom_path : '/'; 2311 var expires = 'Expires=Thu, 01 Jan 1970 00:00:01 GMT;'; 2312 2313 for(var i=0; i<cookies.length; i++){ 2314 for(var j=0; j<domains.length; j++){ 2315 document.cookie = cookies[i] + '=; path=' + path + '; ' + expires + ' Domain=' + domains[j]; 2316 _log("CookieConsent [AUTOCLEAR]: deleting cookie: '" + cookies[i] + "' path: '" + path + "' domain:", domains); 2317 } 2318 } 2319 } 2320 2321 /** 2322 * Returns true if cookie was found and has valid value (not empty string) 2323 * @param {string} cookie_name 2324 * @returns {boolean} 2325 */ 2326 _cookieconsent.validCookie = function(cookie_name){ 2327 return _getCookie(cookie_name, 'one', true) !== ""; 2328 } 2329 2330 /** 2331 * Function to run when event is fired 2332 * @callback eventFired 2333 */ 2334 2335 /** 2336 * Add event listener to dom object (cross browser function) 2337 * @param {Element} elem 2338 * @param {string} event 2339 * @param {eventFired} fn 2340 * @param {boolean} [isPassive] 2341 */ 2342 var _addEvent = function(elem, event, fn, isPassive) { 2343 elem.addEventListener(event, fn , isPassive === true ? { passive: true } : false); 2344 } 2345 2346 /** 2347 * Get all prop. keys defined inside object 2348 * @param {Object} obj 2349 */ 2350 var _getKeys = function(obj){ 2351 if(typeof obj === "object"){ 2352 return Object.keys(obj); 2353 } 2354 } 2355 2356 /** 2357 * Append class to the specified dom element 2358 * @param {HTMLElement} elem 2359 * @param {string} classname 2360 */ 2361 var _addClass = function (elem, classname){ 2362 elem.classList.add(classname); 2363 } 2364 2365 /** 2366 * Remove specified class from dom element 2367 * @param {HTMLElement} elem 2368 * @param {string} classname 2369 */ 2370 var _removeClass = function (el, className) { 2371 el.classList.remove(className); 2372 } 2373 2374 /** 2375 * Check if html element has class 2376 * @param {HTMLElement} el 2377 * @param {string} className 2378 */ 2379 var _hasClass = function(el, className) { 2380 return el.classList.contains(className); 2381 } 2382 2383 // @Visaoi: Checa se já foi aceito 2384 var cookied = JSON.parse(_getCookie(_config.cookie_name, 'one', true) || "{}"); 2385 2386 if (cookied["categories"] && cookied["categories"].length > 0) { 2387 cookied["categories"]?.forEach(function (item) { 2388 VisaoiCookies.stack[item]?.forEach(f => f()) 2389 }); 2390 } 2391 2392 return _cookieconsent; 2393 }; 2394 2395 var init = 'initCookieConsent'; 2396 /** 2397 * Make CookieConsent object accessible globally 2398 */ 2399 if(typeof window !== 'undefined' && typeof window[init] !== 'function'){ 2400 window[init] = CookieConsent 2401 } 2402})();
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.