1/** 2 * @file 3 * eu_cookie_compliance.js 4 * 5 * Defines the behavior of the eu cookie compliance banner. 6 * 7 * Statuses: 8 * null: not yet agreed (or withdrawn), show popup 9 * 0: Disagreed 10 * 1: Agreed, show thank you banner 11 * 2: Agreed 12 */ 13 14(function ($, Drupal, drupalSettings, cookies) { 15 16 'use strict'; 17 var euCookieComplianceBlockCookies; 18 var cookieValueDisagreed = (typeof drupalSettings.eu_cookie_compliance.cookie_value_disagreed === 'undefined' || drupalSettings.eu_cookie_compliance.cookie_value_disagreed === '') ? '0' : drupalSettings.eu_cookie_compliance.cookie_value_disagreed; 19 var cookieValueAgreedShowThankYou = (typeof drupalSettings.eu_cookie_compliance.cookie_value_agreed_show_thank_you === 'undefined' || drupalSettings.eu_cookie_compliance.cookie_value_agreed_show_thank_you === '') ? '1' : drupalSettings.eu_cookie_compliance.cookie_value_agreed_show_thank_you; 20 var cookieValueAgreed = (typeof drupalSettings.eu_cookie_compliance.cookie_value_agreed === 'undefined' || drupalSettings.eu_cookie_compliance.cookie_value_agreed === '') ? '2' : drupalSettings.eu_cookie_compliance.cookie_value_agreed; 21 22 Drupal.behaviors.euCookieCompliancePopup = { 23 attach: function (context) { 24 if (typeof drupalSettings.eu_cookie_compliance !== 'undefined') { 25 const element = document.querySelector(drupalSettings.eu_cookie_compliance.containing_element); 26 if (!element.getAttribute('data-eu-cookie-compliance-once')) { 27 element.setAttribute('data-eu-cookie-compliance-once', 'true'); 28 } else { 29 return; 30 } 31 // Initialize internal variables. 32 _euccCurrentStatus = self.getCurrentStatus(); 33 _euccSelectedCategories = self.getAcceptedCategories(); 34 // If configured, check JSON callback to determine if in EU. 35 if (drupalSettings.eu_cookie_compliance.popup_eu_only_js) { 36 if (Drupal.eu_cookie_compliance.showBanner()) { 37 var url = drupalSettings.path.baseUrl + drupalSettings.path.pathPrefix + 'eu-cookie-compliance-check'; 38 var data = {}; 39 $.getJSON(url, data, function (data) { 40 // If in the EU, show the compliance banner. 41 if (data.in_eu) { 42 Drupal.eu_cookie_compliance.execute(); 43 } 44 45 // If not in EU, set an agreed cookie automatically. 46 else { 47 Drupal.eu_cookie_compliance.setStatus(cookieValueAgreed); 48 // Set the geoip_match to false so it can be used elsewhere. 49 drupalSettings.eu_cookie_compliance.geoip_match = false; 50 if (!euCookieComplianceHasLoadedScripts && typeof euCookieComplianceLoadScripts === "function") { 51 euCookieComplianceLoadScripts(); 52 } 53 // Also set all the categories as agreed if applicable, and load 54 // scripts. 55 if (drupalSettings.eu_cookie_compliance.method === 'categories') { 56 var categories = drupalSettings.eu_cookie_compliance.cookie_categories; 57 Drupal.eu_cookie_compliance.setAcceptedCategories(categories); 58 Drupal.eu_cookie_compliance.loadCategoryScripts(categories); 59 } 60 } 61 }); 62 } 63 } 64 65 // Otherwise, fallback to standard behavior which is to render the banner. 66 else if (!drupalSettings.eu_cookie_compliance.hide_the_banner) { 67 Drupal.eu_cookie_compliance.execute(); 68 } 69 $(element).addClass('eu-cookie-compliance-status-' + Drupal.eu_cookie_compliance.getCurrentStatus()); 70 } 71 }, 72 }; 73 74 // Set up the namespace as a function to store list of arguments in a queue. 75 Drupal.eu_cookie_compliance = Drupal.eu_cookie_compliance || function () { 76 (Drupal.eu_cookie_compliance.queue = Drupal.eu_cookie_compliance.queue || []).push(arguments) 77 }; 78 // Initialize the object with some data. 79 Drupal.eu_cookie_compliance.a = +new Date; 80 // A shorter name to use when accessing the namespace. 81 var self = Drupal.eu_cookie_compliance; 82 // Save our cookie preferences locally only. 83 // Used by external scripts to modify data before it is used. 84 var _euccSelectedCategories = []; 85 var _euccCurrentStatus = null; 86 self.updateSelectedCategories = function (categories) { 87 _euccSelectedCategories = categories; 88 } 89 self.updateCurrentStatus = function (status) { 90 _euccCurrentStatus = status; 91 } 92 93 Drupal.eu_cookie_compliance.execute = function () { 94 try { 95 if (!drupalSettings.eu_cookie_compliance.popup_enabled) { 96 return; 97 } 98 99 if (!Drupal.eu_cookie_compliance.cookiesEnabled()) { 100 return; 101 } 102 103 if (!drupalSettings.eu_cookie_compliance.modules_allow_popup) { 104 return; 105 } 106 107 _euccCurrentStatus = Drupal.eu_cookie_compliance.getCurrentStatus(); 108 109 if (typeof Drupal.eu_cookie_compliance.getVersion() === 'undefined') { 110 // If version doesn't exist as a cookie, set it to a default one. 111 // For sites who update to this version of the module, it helps to 112 // re-trigger the popup in case you switched to category based consent. 113 // For first time runs, it makes no difference as the other IF statements 114 // below will still cause the popup to trigger 115 // For incrementing the version, it also makes no difference as either it's
116 // a returning user and will have a version set, or it's a new user and 117 // the other checks will trigger it. 118 Drupal.eu_cookie_compliance.setVersion(drupalSettings.eu_cookie_compliance.cookie_policy_version); 119 } 120 121 if (drupalSettings.eu_cookie_compliance.popup_eu_only === true && drupalSettings.eu_cookie_compliance.geoip_match !== true) { 122 return; 123 } 124 125 var versionChanged = Drupal.eu_cookie_compliance.getVersion() !== drupalSettings.eu_cookie_compliance.cookie_policy_version; 126 127 // Closed if status has a value and the version hasn't changed or user has not agreed. 128 var cookieName = (typeof drupalSettings.eu_cookie_compliance.cookie_name === 'undefined' || drupalSettings.eu_cookie_compliance.cookie_name === '') ? 'cookie-agreed' : drupalSettings.eu_cookie_compliance.cookie_name; 129 var closed = !drupalSettings.eu_cookie_compliance.open_by_default || 130 (_euccCurrentStatus !== null && !versionChanged || (cookies.get(cookieName) === 'null' && drupalSettings.eu_cookie_compliance.settings_tab_enabled)); 131 132 // Only worried about OPT_IN / GDPR method at present for the perm. settings tab. 133 if (_euccCurrentStatus === cookieValueDisagreed && drupalSettings.eu_cookie_compliance.settings_tab_enabled && (drupalSettings.eu_cookie_compliance.method === 'opt_in' || drupalSettings.eu_cookie_compliance.method === 'categories')) { 134 Drupal.eu_cookie_compliance.createPopup(drupalSettings.eu_cookie_compliance.popup_html_info, (_euccCurrentStatus !== null)); 135 $('.eu-cookie-withdraw-tab').click(Drupal.eu_cookie_compliance.toggleWithdrawBanner); 136 Drupal.eu_cookie_compliance.attachAgreeEvents(); 137 } 138 else if ((_euccCurrentStatus === cookieValueDisagreed && drupalSettings.eu_cookie_compliance.method === 'default') || _euccCurrentStatus === null || (_euccCurrentStatus !== cookieValueDisagreed && drupalSettings.eu_cookie_compliance.withdraw_enabled && drupalSettings.eu_cookie_compliance.withdraw_button_on_info_popup) || (_euccCurrentStatus !== cookieValueDisagreed && versionChanged)) { 139 if (drupalSettings.eu_cookie_compliance.withdraw_enabled || !drupalSettings.eu_cookie_compliance.disagree_do_not_show_popup || _euccCurrentStatus === null) { 140 // Detect mobile here and use mobile_popup_html_info, if we have a mobile device. 141 if (window.matchMedia('(max-width: ' + drupalSettings.eu_cookie_compliance.mobile_breakpoint + 'px)').matches && drupalSettings.eu_cookie_compliance.use_mobile_message) { 142 Drupal.eu_cookie_compliance.createPopup(drupalSettings.eu_cookie_compliance.mobile_popup_html_info, closed); 143 } 144 else { 145 Drupal.eu_cookie_compliance.createPopup(drupalSettings.eu_cookie_compliance.popup_html_info, closed); 146 } 147 Drupal.eu_cookie_compliance.initPopup(); 148 Drupal.eu_cookie_compliance.resizeListener(); 149 } 150 } 151 else if (_euccCurrentStatus === cookieValueAgreedShowThankYou && drupalSettings.eu_cookie_compliance.popup_agreed_enabled) { 152 // Thank you banner. 153 Drupal.eu_cookie_compliance.createPopup(drupalSettings.eu_cookie_compliance.popup_html_agreed); 154 Drupal.eu_cookie_compliance.attachHideEvents(); 155 } 156 else if (_euccCurrentStatus === cookieValueAgreed && drupalSettings.eu_cookie_compliance.withdraw_enabled) { 157 if (!drupalSettings.eu_cookie_compliance.withdraw_button_on_info_popup) { 158 Drupal.eu_cookie_compliance.createWithdrawBanner(drupalSettings.eu_cookie_compliance.withdraw_markup); 159 Drupal.eu_cookie_compliance.initPopup(); 160 Drupal.eu_cookie_compliance.resizeListener(); 161 } 162 } 163 } 164 catch (e) { 165 } 166 }; 167 168 Drupal.eu_cookie_compliance.initPopup = function () { 169 Drupal.eu_cookie_compliance.attachAgreeEvents(); 170 171 if (drupalSettings.eu_cookie_compliance.method === 'categories') { 172 Drupal.eu_cookie_compliance.setPreferenceCheckboxes(_euccSelectedCategories); 173 Drupal.eu_cookie_compliance.attachSavePreferencesEvents(); 174 } 175 176 if (drupalSettings.eu_cookie_compliance.withdraw_enabled) { 177 Drupal.eu_cookie_compliance.attachWithdrawEvents();
178 if (_euccCurrentStatus === cookieValueAgreedShowThankYou || _euccCurrentStatus === cookieValueAgreed) { 179 $('.eu-cookie-withdraw-button').removeClass('visually-hidden'); 180 $('.eu-cookie-compliance-reject-button').addClass('visually-hidden'); 181 } 182 } 183 } 184 185 Drupal.eu_cookie_compliance.positionTab = function () { 186 if (drupalSettings.eu_cookie_compliance.popup_position) { 187 let totalHeight = $('.eu-cookie-withdraw-tab').outerHeight(); 188 if ($('#sliding-popup').length) { 189 totalHeight += $('#sliding-popup').outerHeight(); 190 } 191 if ($('.eu-cookie-withdraw-wrapper').length) { 192 $('.eu-cookie-withdraw-tab').css('margin-top', '0'); 193 } 194 else { 195 $('.eu-cookie-withdraw-tab').css('margin-top', totalHeight + 'px'); 196 } 197 } 198 }; 199 200 Drupal.eu_cookie_compliance.createWithdrawBanner = function (html) { 201 var $html = $('<div></div>').html(html); 202 var $banner = $('.eu-cookie-withdraw-banner', $html); 203 $html.attr({ 204 'id': 'sliding-popup', 205 'class': 'fr-consent-banner', 206 //'role': 'dialog', 207 //'aria-labelledby': 'popup-title', 208 }); 209 $html.addClass('eu-cookie-withdraw-wrapper'); 210 211 $html.trigger('eu_cookie_compliance_popup_close'); 212 213 if (!drupalSettings.eu_cookie_compliance.popup_use_bare_css && !drupalSettings.eu_cookie_compliance.popup_use_olivero_css) { 214 $banner.height(drupalSettings.eu_cookie_compliance.popup_height) 215 .width(drupalSettings.eu_cookie_compliance.popup_width); 216 } 217 $html.hide(); 218 var height = 0; 219 if (drupalSettings.eu_cookie_compliance.popup_position) { 220 $html.prependTo(drupalSettings.eu_cookie_compliance.containing_element); 221 height = parseInt($html.outerHeight()); 222 223 $html.show() 224 .addClass('sliding-popup-top') 225 .addClass('clearfix') 226 .css({ top: Drupal.eu_cookie_compliance.getBannerTopHiddenPosition(height)}); 227 // For some reason, the tab outerHeight is -10 if we don't use a timeout 228 // function to reveal the tab. 229 setTimeout(function () { 230 var height = $html.outerHeight(); 231 232 $html.animate({ top: Drupal.eu_cookie_compliance.getBannerTopHiddenPosition(height) }, drupalSettings.eu_cookie_compliance.popup_delay, null); 233 if (!drupalSettings.eu_cookie_compliance.fixed_top_position) { 234 $('body').animate({ 'margin-top': -height + 'px' }); 235 } 236 }.bind($html), 0); 237 } 238 else { 239 if (drupalSettings.eu_cookie_compliance.better_support_for_screen_readers) { 240 $html.prependTo(drupalSettings.eu_cookie_compliance.containing_element); 241 } 242 else { 243 $html.appendTo(drupalSettings.eu_cookie_compliance.containing_element); 244 } 245 height = $html.outerHeight(); 246 $html.show() 247 .addClass('sliding-popup-bottom') 248 .css({ bottom: -1 * height }); 249 // For some reason, the tab outerHeight is -10 if we don't use a timeout 250 // function to reveal the tab. 251 setTimeout(function () { 252 var height = $html.outerHeight(); 253 254 $html.animate({ bottom: -1 * (height) }, drupalSettings.eu_cookie_compliance.popup_delay, null); 255 }.bind($html), 0); 256 } 257 $('body').removeClass('eu-cookie-compliance-popup-open'); 258 $banner 259 .attr('aria-hidden', true) 260 .find('a, button, input') 261 .attr('tabindex', -1); 262 }; 263 264 Drupal.eu_cookie_compliance.getBannerTopPosition = function (height) { 265 let bannerTopPosition; 266 if (drupalSettings.eu_cookie_compliance.fixed_top_position) { 267 bannerTopPosition = 0; 268 } 269 else { 270 return 0; 271 } 272 273 if ($('.toolbar-tray-horizontal.is-active').length) { 274 bannerTopPosition += parseInt($('.toolbar-tray-horizontal.is-active').css('height')); 275 } 276 277 if ($('.toolbar-bar').length && !$('#gin-toolbar-bar').length) { 278 bannerTopPosition += parseInt($('.toolbar-bar').css('height')); 279 } 280 281 return bannerTopPosition + 'px'; 282 } 283 284 Drupal.eu_cookie_compliance.getBannerTopHiddenPosition = function (height) { 285 let bannerTopPosition = 0; 286 if (drupalSettings.eu_cookie_compliance.fixed_top_position) { 287 bannerTopPosition = -height; 288 } 289 else { 290 if ($('.toolbar-tray-horizontal.is-active').length) { 291 bannerTopPosition = -parseInt($('.toolbar-tray-horizontal.is-active').css('height')); 292 } 293 294 if ($('.toolbar-bar').length && !$('#gin-toolbar-bar').length) { 295 bannerTopPosition -= parseInt($('.toolbar-bar').css('height')); 296 } 297 } 298 299 return bannerTopPosition + 'px'; 300 } 301 302 Drupal.eu_cookie_compliance.getBannerBottomHiddenPosition = function () { 303 return -($('#sliding-popup').outerHeight()) + 'px'; 304 } 305 306 Drupal.eu_cookie_compliance.toggleWithdrawBanner = function () { 307 var $wrapper = $('#sliding-popup'); 308 var height = parseInt($wrapper.outerHeight()); 309 var bannerIsShowing = ($wrapper.find('.eu-cookie-compliance-banner, .eu-cookie-withdraw-banner').is(':visible')); 310 if (bannerIsShowing) { 311 let bannerTop = parseInt($wrapper.css('top')); 312 let containerPadding = parseInt($(drupalSettings.eu_cookie_compliance.containing_element).css('padding-top')); 313 let containerMargin = parseInt($(drupalSettings.eu_cookie_compliance.containing_element).css('margin-top')); 314 315 if (drupalSettings.eu_cookie_compliance.popup_position) { 316 if (drupalSettings.eu_cookie_compliance.fixed_top_position) { 317 bannerIsShowing = !(bannerTop === -height); 318 } 319 else { 320 bannerIsShowing = !(bannerTop === -(containerPadding + containerMargin + he
320ight)); 321 } 322 } 323 else { 324 bannerIsShowing = (parseInt($wrapper.css('bottom')) === 0); 325 } 326 } 327 if (drupalSettings.eu_cookie_compliance.popup_position) { 328 if (bannerIsShowing) { 329 if (!drupalSettings.eu_cookie_compliance.fixed_top_position) { 330 $('body').animate({ 'margin-top': -height + 'px' }, drupalSettings.eu_cookie_compliance.popup_delay); 331 } 332 $wrapper.animate({ top: Drupal.eu_cookie_compliance.getBannerTopHiddenPosition(height) }, drupalSettings.eu_cookie_compliance.popup_delay).trigger('eu_cookie_compliance_popup_close'); 333 } 334 else { 335 // If "Do not show cookie policy when the user clicks the Cookie policy button." is 336 // selected, the inner banner may be hidden. 337 if (!drupalSettings.eu_cookie_compliance.fixed_top_position) { 338 $('body').animate({ 'margin-top': '0px' }, drupalSettings.eu_cookie_compliance.popup_delay); 339 } 340 $wrapper.find('.eu-cookie-compliance-banner').show(); 341 $wrapper.animate({ top: Drupal.eu_cookie_compliance.getBannerTopPosition(height) }, drupalSettings.eu_cookie_compliance.popup_delay).trigger('eu_cookie_compliance_popup_open'); 342 } 343 } 344 else { 345 if (bannerIsShowing) { 346 $wrapper.animate({ 'bottom': -1 * (height) }, drupalSettings.eu_cookie_compliance.popup_delay).trigger('eu_cookie_compliance_popup_close'); 347 } 348 else { 349 // If "Do not show cookie policy when the user clicks the Cookie policy button." is 350 // selected, the inner banner may be hidden. 351 $wrapper.find('.eu-cookie-compliance-banner').show(); 352 $wrapper.animate({ 'bottom': 0 }, drupalSettings.eu_cookie_compliance.popup_delay).trigger('eu_cookie_compliance_popup_open'); 353 } 354 } 355 if (bannerIsShowing) { 356 $('body').removeClass('eu-cookie-compliance-popup-open'); 357 $('.eu-cookie-compliance-banner, .eu-cookie-withdraw-banner') 358 .attr('aria-hidden', true) 359 .find('a, button, input') 360 .attr('tabindex', -1); 361 } 362 else { 363 $('body').addClass('eu-cookie-compliance-popup-open'); 364 $('.eu-cookie-compliance-banner, .eu-cookie-withdraw-banner') 365 .attr('aria-hidden', false) 366 .find('a, button, input') 367 .attr('tabindex', 0); 368 } 369 }; 370 371 Drupal.eu_cookie_compliance.resizeListener = function () { 372 var $wrapper = $('#sliding-popup'); 373 374 var debounce = function (func, wait) { 375 var timeout; 376 377 return function executedFunction() { 378 var later = function () { 379 clearTimeout(timeout); 380 func(); 381 }; 382 383 clearTimeout(timeout); 384 timeout = setTimeout(later, wait); 385 }; 386 }; 387 388 var checkIfPopupIsClosed = debounce(function () { 389 var wrapperHeight = $wrapper.outerHeight(); 390 if (drupalSettings.eu_cookie_compliance.popup_position) { 391 var wrapperTopProperty = parseFloat($wrapper.css('top')); 392 if (wrapperTopProperty < 0) { 393 if ($('body').hasClass('eu-cookie-compliance-popup-open')) { 394 if (!drupalSettings.eu_cookie_compliance.fixed_top_position) { 395 $('body').css({ 'margin-top': '0px' }); 396 } 397 $wrapper.css('top', Drupal.eu_cookie_compliance.getBannerTopPosition(wrapperHeight)); 398 } 399 else { 400 if (!drupalSettings.eu_cookie_compliance.fixed_top_position) { 401 $('body').css({ 'margin-top': -wrapperHeight + 'px' }); 402 } 403 $wrapper.css('top', Drupal.eu_cookie_compliance.getBannerTopHiddenPosition(wrapperHeight)); 404 } 405 } 406 Drupal.eu_cookie_compliance.positionTab(); 407 } 408 else { 409 var wrapperBottomProperty = parseFloat($wrapper.css('bottom')); 410 if (wrapperBottomProperty !== 0) { 411 $wrapper.css('bottom', wrapperHeight * -1); 412 } 413 } 414 Drupal.eu_cookie_compliance.positionTab(); 415 }, 50); 416 417 setTimeout(function () { 418 checkIfPopupIsClosed(); 419 }); 420 421 window.addEventListener('resize', checkIfPopupIsClosed); 422 }; 423 424 Drupal.eu_cookie_compliance.createPopup = function (html, closed) { 425 // This fixes a problem with jQuery 1.9. 426 var popup = $('<div></div>').html(html); 427 popup.attr({ 428 'id': 'sliding-popup', 429 'class': 'fr-consent-banner', 430 //'role': 'dialog', 431 'aria-labelledby': 'popup-title', 432 }); 433 if (!drupalSettings.eu_cookie_compliance.popup_use_bare_css && !drupalSettings.eu_cookie_compliance.popup_use_olivero_css) { 434 popup.height(drupalSettings.eu_cookie_compliance.popup_height) 435 .width(drupalSettings.eu_cookie_compliance.popup_width); 436 } 437 438 popup.hide(); 439 var height = 0; 440 if (drupalSettings.eu_cookie_compliance.popup_position) { 441 popup.prependTo(drupalSettings.eu_cookie_compliance.containing_element); 442 height = popup.outerHeight(); 443 popup.addClass('sliding-popup-top clearfix') 444 .css({ top: Drupal.eu_cookie_compliance.getBannerTopHiddenPosition(height) }); 445 446 if (closed !== true) { 447 popup.show(); 448 popup.animate({top: Drupal.eu_cookie_compliance.getBannerTopPosition(height)}, drupalSettings.eu_cookie_compliance.popup_delay, null, function () { 449 popup.trigger('eu_cookie_compliance_popup_open'); 450 Drupal.eu_cookie_compliance.positionTab(); 451 }); 452 } 453 else { 454 if (!drupalSettings.eu_cookie_compliance.fixed_top_position) { 455 $('body').css({ 'margin-top': -height + 'px' }); 456 } 457 setTimeout(function () { 458 popup.show(); 459 Drupal.eu_cookie_compliance.positionTab(); 460 }, 0); 461 } 462 } 463 else { 464 if (drupalSettings.eu_cookie_compliance.better_support_for_screen_readers) { 465 popup.prependTo(drupalSettings.eu_cookie_compliance.containing_element); 466 } 467 else { 468 popup.appendTo(drupalSettings.eu_cookie_compliance.containing_element); 469 } 470 471 height = popup.outerHeight(); 472 popup.show() 473 .addClass('sliding-popup-bottom') 474 .css({bottom: -1 * height}); 475 476 if (closed !== true) { 477 popup.animate({bottom: 0}, drupalSettings.eu_cookie_compliance.popup_delay, null, function () { 478 popup.trigger('eu_cookie_compliance_popup_open'); 479 }); 480 } 481 } 482 if (closed !== true) { 483 $('body').addClass('eu-cookie-compliance-popup-open'); 484 $('.eu-cookie-compliance-banner, .eu-cookie-withdraw-banner') 485 .attr('aria-hidden', false) 486 .find('a, button, input') 487 .attr('tabindex', 0); 488 } 489 else { 490 $('body').removeClass('eu-cookie-compliance-popup-open'); 491 $('.eu-cookie-compliance-banner, .eu-cookie-withdraw-banner') 492 .attr('aria-hidden', true) 493 .find('a, button, input') 494 .attr('tabindex', -1); 495 } 496 }; 497 498 Drupal.eu_cookie_compliance.attachAgreeEvents = function () { 499 var clickingConfirms = drupalSettings.eu_cookie_compliance.popup_clicking_confirmation; 500 var scrollConfirms = drupalSettings.eu_cookie_compliance.popup_scrolling_confirmation; 501 502 if (drupalSettings.eu_cookie_compliance.method === 'categories' && drupalSettings.eu_cookie_compliance.enable_save_preferences_button) { 503 // The agree button becomes an agree to all categories button when the 'save preferences' button is present. 504 $('.agree-button').click(Drupal.eu_cookie_compliance.acceptAllAction); 505 } 506 else { 507 $('.agree-button').click(Drupal.eu_cookie_compliance.acceptAction); 508 } 509 $('.decline-button').click(Drupal.eu_cookie_compliance.declineAction); 510 $('.eu-cookie-compliance-close-button').click(Drupal.eu_cookie_compliance.closeAction); 511 $('.eu-cookie-compliance-reject-button').click(Drupal.eu_cookie_compliance.rejectAllAction); 512 513 if (clickingConfirms) { 514 $('a, input[type=submit], button[type=submit]').not('.popup-content *').bind('click.euCookieCompliance', Drupal.eu_cookie_compliance.acceptAction); 515 } 516 517 if (scrollConfirms) { 518 var alreadyScrolled = false;
519 var scrollHandler = function () { 520 if (alreadyScrolled) { 521 Drupal.eu_cookie_compliance.acceptAction(); 522 $(window).off('scroll', scrollHandler); 523 } 524 else { 525 alreadyScrolled = true; 526 } 527 }; 528 529 $(window).bind('scroll', scrollHandler); 530 } 531 532 $('.find-more-button').not('.find-more-button-processed').addClass('find-more-button-processed').click(Drupal.eu_cookie_compliance.moreInfoAction); 533 }; 534 535 Drupal.eu_cookie_compliance.closeAction = function () { 536 switch (drupalSettings.eu_cookie_compliance.close_button_action) { 537 case 'close_banner': 538 Drupal.eu_cookie_compliance.toggleWithdrawBanner(); 539 break; 540 541 case 'save_preferences': 542 Drupal.eu_cookie_compliance.savePreferencesAction(); 543 break; 544 545 case 'reject_all_cookies': 546 Drupal.eu_cookie_compliance.rejectAllAction(); 547 break; 548 549 case 'accept_all_cookies': 550 Drupal.eu_cookie_compliance.acceptAllAction(); 551 break; 552 } 553 }; 554 555 Drupal.eu_cookie_compliance.attachSavePreferencesEvents = function () { 556 $('.eu-cookie-compliance-save-preferences-button').click(Drupal.eu_cookie_compliance.savePreferencesAction); 557 }; 558 559 Drupal.eu_cookie_compliance.attachHideEvents = function () { 560 var popupHideAgreed = drupalSettings.eu_cookie_compliance.popup_hide_agreed; 561 var clickingConfirms = drupalSettings.eu_cookie_compliance.popup_clicking_confirmation; 562 $('.hide-popup-button').click(function () { 563 Drupal.eu_cookie_compliance.changeStatus(cookieValueAgreed); 564 } 565 ); 566 if (clickingConfirms) { 567 $('a, input[type=submit], button[type=submit]').unbind('click.euCookieCompliance'); 568 } 569 570 if (popupHideAgreed) { 571 $('a, input[type=submit], button[type=submit]').bind('click.euCookieComplianceHideAgreed', function () { 572 Drupal.eu_cookie_compliance.changeStatus(cookieValueAgreed); 573 }); 574 } 575 576 $('.find-more-button').not('.find-more-button-processed').addClass('find-more-button-processed').click(Drupal.eu_cookie_compliance.moreInfoAction); 577 }; 578 579 Drupal.eu_cookie_compliance.attachWithdrawEvents = function () { 580 $('.eu-cookie-withdraw-button').click(Drupal.eu_cookie_compliance.withdrawAction); 581 $('.eu-cookie-withdraw-tab').click(Drupal.eu_cookie_compliance.toggleWithdrawBanner); 582 }; 583 584 Drupal.eu_cookie_compliance.acceptAction = function () { 585 var agreedEnabled = drupalSettings.eu_cookie_compliance.popup_agreed_enabled; 586 var nextStatus = cookieValueAgreedShowThankYou; 587 if (!agreedEnabled) { 588 Drupal.eu_cookie_compliance.setStatus(cookieValueAgreedShowThankYou); 589 nextStatus = cookieValueAgreed; 590 } 591 592 if (!euCookieComplianceHasLoadedScripts && typeof euCookieComplianceLoadScripts === "function") { 593 euCookieComplianceLoadScripts(); 594 } 595 596 if (typeof euCookieComplianceBlockCookies !== 'undefined') { 597 clearInterval(euCookieComplianceBlockCookies); 598 } 599 600 if (drupalSettings.eu_cookie_compliance.method === 'categories') { 601 // Select Checked categories. 602 var categories = $("#eu-cookie-compliance-categories input:checkbox:checked").map(function () { 603 return $(this).val(); 604 }).get(); 605 Drupal.eu_cookie_compliance.setAcceptedCategories(categories); 606 // Load scripts for all categories. If no categories selected, none 607 // will be loaded. 608 Drupal.eu_cookie_compliance.loadCategoryScripts(categories); 609 if (!categories.length) { 610 // No categories selected is the same as declining all cookies. 611 nextStatus = cookieValueDisagreed; 612 } 613 } 614 615 Drupal.eu_cookie_compliance.changeStatus(nextStatus); 616 617 if (drupalSettings.eu_cookie_compliance.withdraw_enabled && drupalSettings.eu_cookie_compliance.withdraw_button_on_info_popup) { 618 Drupal.eu_cookie_compliance.attachWithdrawEvents(); 619 if (_euccCurrentStatus === cookieValueAgreedShowThankYou || _euccCurrentStatus === cookieValueAgreed) { 620 $('.eu-cookie-withdraw-button').removeClass('visually-hidden'); 621 $('.eu-cookie-compliance-reject-button').addClass('visually-hidden'); 622 } 623 } 624 }; 625 626 Drupal.eu_cookie_compliance.acceptAllAction = function () { 627 var allCategories = drupalSettings.eu_cookie_compliance.cookie_categories; 628 Drupal.eu_cookie_compliance.setPreferenceCheckboxes(allCategories); 629 Drupal.eu_cookie_compliance.acceptAction(); 630 } 631 632 Drupal.eu_cookie_compliance.rejectAllAction = function () { 633 Drupal.eu_cookie_compliance.setPreferenceCheckboxes([]); 634 Drupal.eu_cookie_compliance.acceptAction(); 635 } 636 637 Drupal.eu_cookie_compliance.savePreferencesAction = function () { 638 var categories = $("#eu-cookie-compliance-categories input:checkbox:checked").map(function () { 639 return $(this).val(); 640 }).get(); 641 var agreedEnabled = drupalSettings.eu_cookie_compliance.popup_agreed_enabled;
642 var nextStatus = cookieValueAgreedShowThankYou; 643 if (!agreedEnabled) { 644 Drupal.eu_cookie_compliance.setStatus(cookieValueAgreedShowThankYou); 645 nextStatus = cookieValueAgreed; 646 } 647 648 Drupal.eu_cookie_compliance.setAcceptedCategories(categories); 649 // Load scripts for all categories. If no categories selected, none 650 // will be loaded. 651 Drupal.eu_cookie_compliance.loadCategoryScripts(categories); 652 if (!categories.length) { 653 // No categories selected is the same as declining all cookies. 654 nextStatus = cookieValueDisagreed; 655 } 656 657 Drupal.eu_cookie_compliance.changeStatus(nextStatus); 658 }; 659 660 Drupal.eu_cookie_compliance.loadCategoryScripts = function (categories) { 661 for (var cat in categories) { 662 if (euCookieComplianceHasLoadedScriptsForCategory[categories[cat]] !== true && typeof euCookieComplianceLoadScripts === "function") { 663 euCookieComplianceLoadScripts(categories[cat]); 664 euCookieComplianceHasLoadedScriptsForCategory[categories[cat]] = true; 665 } 666 } 667 } 668 669 Drupal.eu_cookie_compliance.declineAction = function () { 670 var set_cookie_session_zero_on_disagree = parseInt(drupalSettings.eu_cookie_compliance.set_cookie_session_zero_on_disagree); 671 if (set_cookie_session_zero_on_disagree) { 672 drupalSettings.eu_cookie_compliance.cookie_session = 1; 673 } 674 Drupal.eu_cookie_compliance.setStatus(cookieValueDisagreed); 675 var popup = $('#sliding-popup'); 676 if (popup.hasClass('sliding-popup-top')) { 677 let height = popup.outerHeight(); 678 if (!drupalSettings.eu_cookie_compliance.fixed_top_position) { 679 $('body').animate({ 'margin-top': -height + 'px' }, drupalSettings.eu_cookie_compliance.popup_delay); 680 } 681 if (drupalSettings.eu_cookie_compliance.settings_tab_enabled) { 682 popup.animate({top: Drupal.eu_cookie_compliance.getBannerTopHiddenPosition(height)}, drupalSettings.eu_cookie_compliance.popup_delay, null).trigger('eu_cookie_compliance_popup_close'); 683 $('.eu-cookie-withdraw-tab').click(Drupal.eu_cookie_compliance.toggleWithdrawBanner); 684 } 685 else { 686 popup.animate({top: Drupal.eu_cookie_compliance.getBannerTopHiddenPosition(height)}, drupalSettings.eu_cookie_compliance.popup_delay, null, function () { 687 popup.hide(); 688 }).trigger('eu_cookie_compliance_popup_close'); 689 } 690 } 691 else { 692 if (drupalSettings.eu_cookie_compliance.settings_tab_enabled) { 693 popup.animate({ bottom: popup.outerHeight() * -1 }, drupalSettings.eu_cookie_compliance.popup_delay, null).trigger('eu_cookie_compliance_popup_close'); 694 $('.eu-cookie-withdraw-tab').click(Drupal.eu_cookie_compliance.toggleWithdrawBanner); 695 } 696 else { 697 popup.animate({ bottom: popup.outerHeight() * -1 }, drupalSettings.eu_cookie_compliance.popup_delay, null, function () { 698 popup.hide(); 699 }).trigger('eu_cookie_compliance_popup_close'); 700 } 701 } 702 $('body').removeClass('eu-cookie-compliance-popup-open'); 703 $('.eu-cookie-compliance-banner, .eu-cookie-withdraw-banner') 704 .attr('aria-hidden', true) 705 .find('a, button, input') 706 .attr('tabindex', -1); 707 }; 708 709 Drupal.eu_cookie_compliance.withdrawAction = function () { 710 var set_cookie_session_zero_on_disagree = parseInt(drupalSettings.eu_cookie_compliance.set_cookie_session_zero_on_disagree); 711 if (set_cookie_session_zero_on_disagree) { 712 drupalSettings.eu_cookie_compliance.cookie_session = 1; 713 } 714 Drupal.eu_cookie_compliance.setStatus(null); 715 Drupal.eu_cookie_compliance.setAcceptedCategories([]); 716 location.reload(); 717 }; 718 719 Drupal.eu_cookie_compliance.moreInfoAction = function () { 720 if (drupalSettings.eu_cookie_compliance.disagree_do_not_show_popup) { 721 Drupal.eu_cookie_compliance.setStatus(cookieValueDisagreed); 722 if (drupalSettings.eu_cookie_compliance.withdraw_enabled && drupalSettings.eu_cookie_compliance.withdraw_button_on_info_popup) { 723 $('#sliding-popup .eu-cookie-compliance-banner').trigger('eu_cookie_compliance_popup_close').hide(); 724 } 725 else { 726 $('#sliding-popup').trigger('eu_cookie_compliance_popup_close').remove(); 727 } 728 $('body').removeClass('eu-cookie-compliance-popup-open'); 729 $('.eu-cookie-compliance-banner, .eu-cookie-withdraw-banner') 730 .attr('aria-hidden', true) 731 .find('a, button, input') 732 .attr('tabindex', -1); 733 } 734 else { 735 if (drupalSettings.eu_cookie_compliance.popup_link_new_window) { 736 window.open(drupalSettings.eu_cookie_compliance.popup_link); 737 } 738 else { 739 window.location.href = drupalSettings.eu_cookie_compliance.popup_link; 740 } 741 } 742 }; 743 744 Drupal.eu_cookie_compliance.getCookieStatus = function () { 745 var cookieName = (typeof drupalSettings.eu_cookie_compliance.cookie_name === 'undefined' || drupalSettings.eu_cookie_compliance.cookie_name === '') ? 'cookie-agreed' : drupalSettings.eu_cookie_compliance.cookie_name;
746 var currentStatus = cookies.get(cookieName); 747 if (typeof currentStatus === 'undefined' || currentStatus === 'null') { 748 currentStatus = null; 749 } 750 return currentStatus; 751 } 752 753 Drupal.eu_cookie_compliance.getCurrentStatus = function () { 754 // Make a new observer & fire it to allow other scripts to hook in. 755 var preStatusLoadObject = new PreStatusLoad(); 756 self.handleEvent('preStatusLoad', preStatusLoadObject); 757 758 _euccCurrentStatus = Drupal.eu_cookie_compliance.getCookieStatus(); 759 760 // Make a new observer & fire it to allow other scripts to hook in. 761 var postStatusLoadObject = new PostStatusLoad(); 762 self.handleEvent('postStatusLoad', postStatusLoadObject); 763 764 return _euccCurrentStatus; 765 }; 766 767 Drupal.eu_cookie_compliance.setPreferenceCheckboxes = function (categories) { 768 if (Drupal.eu_cookie_compliance.getCookieStatus() !== null || Drupal.eu_cookie_compliance.getCookieStatus() === cookieValueDisagreed) { 769 // Unset all categories to prevent a problem where the checkboxes with a 770 // default state set would always show up as checked. 771 $("#eu-cookie-compliance-categories input:checkbox").not(":disabled").prop("checked", false); 772 } 773 // Check the appropriate checkboxes. 774 for (var i in categories) { 775 var categoryElement = document.getElementById('cookie-category-' + categories[i]); 776 if (categoryElement !== null) { 777 categoryElement.checked = true; 778 } 779 } 780 } 781 782 Drupal.eu_cookie_compliance.getAcceptedCategories = function () { 783 // Make a new observer & fire it to allow other scripts to hook in. 784 var prePreferencesLoadObject = new PrePreferencesLoad(); 785 self.handleEvent('prePreferencesLoad', prePreferencesLoadObject); 786 787 var cookieName = (typeof drupalSettings.eu_cookie_compliance.cookie_name === 'undefined' || drupalSettings.eu_cookie_compliance.cookie_name === '') ? 'cookie-agreed-categories' : drupalSettings.eu_cookie_compliance.cookie_name + '-categories'; 788 var storedCategories = cookies.get(cookieName); 789 790 if (storedCategories !== null && typeof storedCategories !== 'undefined') { 791 // JS cookie introduced unescaped cookie values. 792 if (storedCategories.indexOf('%') !== -1) { 793 storedCategories = decodeURI(storedCategories).replaceAll(/%2C/g, ','); 794 } 795 _euccSelectedCategories = JSON.parse(storedCategories); 796 } 797 else { 798 _euccSelectedCategories = []; 799 } 800 801 // Merge in required categories if not already present. Mimics old 802 // logic where "fix first category" changed logic in 803 // .hasAgreedWithCategory and this function. 804 for (var _categoryName in drupalSettings.eu_cookie_compliance.cookie_categories_details) { 805 var _category = drupalSettings.eu_cookie_compliance.cookie_categories_details[_categoryName]; 806 if (_category.checkbox_default_state === 'required' && $.inArray(_category.id, _euccSelectedCategories) === -1) { 807 _euccSelectedCategories.push(_category.id); 808 } 809 } 810 811 // Make a new observer & fire it to allow other scripts to hook in. 812 var postPreferencesLoadObject = new PostPreferencesLoad(); 813 self.handleEvent('postPreferencesLoad', postPreferencesLoadObject); 814 815 return _euccSelectedCategories; 816 }; 817 818 Drupal.eu_cookie_compliance.changeStatus = function (value) { 819 var reloadPage = drupalSettings.eu_cookie_compliance.reload_page; 820 var previousState = _euccCurrentStatus; 821 if (_euccCurrentStatus === parseInt(value)) { 822 return; 823 } 824 825 if (drupalSettings.eu_cookie_compliance.popup_position) { 826 let height = $('#sliding-popup').outerHeight(); 827 if (!drupalSettings.eu_cookie_compliance.fixed_top_position) { 828 $('body').animate({ 'margin-top': -height + 'px' }, drupalSettings.eu_cookie_compliance.popup_delay); 829 } 830 $('.sliding-popup-top').animate({ top: Drupal.eu_cookie_compliance.getBannerTopHiddenPosition(height) }, drupalSettings.eu_cookie_compliance.popup_delay, function () { 831 if (value === cookieValueAgreedShowThankYou && previousState === null && !reloadPage) { 832 if (!drupalSettings.eu_cookie_compliance.fixed_top_position) { 833 $('body').animate({ 'margin-top': '0px' }, drupalSettings.eu_cookie_compliance.popup_delay); 834 } 835 $('.sliding-popup-top').not('.eu-cookie-withdraw-wrapper').html(drupalSettings.eu_cookie_compliance.popup_html_agreed).animate({ top: Drupal.eu_cookie_compliance.getBannerTopPosition(height) }, drupalSettings.eu_cookie_compliance.popup_delay); 836 Drupal.eu_cookie_compliance.attachHideEvents(); 837 }
838 else if (previousState === cookieValueAgreedShowThankYou) { 839 if (drupalSettings.eu_cookie_compliance.withdraw_enabled && drupalSettings.eu_cookie_compliance.withdraw_button_on_info_popup) { 840 $('#sliding-popup').hide(); 841 // Restore popup content. 842 if (window.matchMedia('(max-width: ' + drupalSettings.eu_cookie_compliance.mobile_breakpoint + 'px)').matches && drupalSettings.eu_cookie_compliance.use_mobile_message) { 843 $('.sliding-popup-top').not('.eu-cookie-withdraw-wrapper').html(drupalSettings.eu_cookie_compliance.mobile_popup_html_info); 844 } 845 else { 846 $('.sliding-popup-top').not('.eu-cookie-withdraw-wrapper').html(drupalSettings.eu_cookie_compliance.popup_html_info); 847 } 848 height = $('#sliding-popup').outerHeight(); 849 if (!drupalSettings.eu_cookie_compliance.fixed_top_position) { 850 $('body').animate({ 'margin-top': -height + 'px' }, drupalSettings.eu_cookie_compliance.popup_delay); 851 } 852 $('.sliding-popup-top').css('top', Drupal.eu_cookie_compliance.getBannerTopHiddenPosition(height)); 853 $('.sliding-popup-top').not('.eu-cookie-withdraw-wrapper').trigger('eu_cookie_compliance_popup_close'); 854 Drupal.eu_cookie_compliance.initPopup(); 855 Drupal.eu_cookie_compliance.resizeListener(); 856 $('#sliding-popup').show(); 857 } 858 else { 859 $('.sliding-popup-top').not('.eu-cookie-withdraw-wrapper').trigger('eu_cookie_compliance_popup_close').remove(); 860 $('body').css({ 'margin-top': '0px' }); 861 } 862 $('body').removeClass('eu-cookie-compliance-popup-open'); 863 $('.eu-cookie-compliance-banner, .eu-cookie-withdraw-banner') 864 .attr('aria-hidden', true) 865 .find('a, button, input') 866 .attr('tabindex', -1); 867 868 869 } 870 if (drupalSettings.eu_cookie_compliance.withdraw_enabled && !drupalSettings.eu_cookie_compliance.withdraw_button_on_info_popup) { 871 Drupal.eu_cookie_compliance.showWithdrawBanner(value); 872 } 873 }); 874 } 875 else { 876 $('.sliding-popup-bottom').animate({ bottom: $('#sliding-popup').outerHeight() * -1 }, drupalSettings.eu_cookie_compliance.popup_delay, function () { 877 if (value === cookieValueAgreedShowThankYou && previousState === null && !reloadPage) { 878 $('.sliding-popup-bottom').not('.eu-cookie-withdraw-wrapper').html(drupalSettings.eu_cookie_compliance.popup_html_agreed).animate({ bottom: 0 }, drupalSettings.eu_cookie_compliance.popup_delay); 879 Drupal.eu_cookie_compliance.attachHideEvents(); 880 } 881 else if (previousState === cookieValueAgreedShowThankYou) { 882 $('#sliding-popup').css('display', 'none'); 883 if (drupalSettings.eu_cookie_compliance.withdraw_enabled && drupalSettings.eu_cookie_compliance.withdraw_button_on_info_popup) { 884 // Restore popup content. 885 if (window.matchMedia('(max-width: ' + drupalSettings.eu_cookie_compliance.mobile_breakpoint + 'px)').matches && drupalSettings.eu_cookie_compliance.use_mobile_message) { 886 $('.sliding-popup-bottom').not('.eu-cookie-withdraw-wrapper').html(drupalSettings.eu_cookie_compliance.mobile_popup_html_info); 887 } 888 else { 889 $('.sliding-popup-bottom').not('.eu-cookie-withdraw-wrapper').html(drupalSettings.eu_cookie_compliance.popup_html_info); 890 } 891 $('.sliding-popup-bottom').css('bottom', Drupal.eu_cookie_compliance.getBannerBottomHiddenPosition()); 892 $('.sliding-popup-bottom').not('.eu-cookie-withdraw-wrapper').trigger('eu_cookie_compliance_popup_close'); 893 Drupal.eu_cookie_compliance.initPopup(); 894 Drupal.eu_cookie_compliance.resizeListener(); 895 $('#sliding-popup').css('display', 'block'); 896 } 897 else { 898 $('.sliding-popup-bottom').not('.eu-cookie-withdraw-wrapper').trigger('eu_cookie_compliance_popup_close').remove(); 899 } 900 $('body').removeClass('eu-cookie-compliance-popup-open'); 901 $('.eu-cookie-compliance-banner, .eu-cookie-withdraw-banner') 902 .attr('aria-hidden', true) 903 .find('a, button, input') 904 .attr('tabindex', -1); 905 } 906 if (drupalSettings.eu_cookie_compliance.withdraw_enabled && !drupalSettings.eu_cookie_compliance.withdraw_button_on_info_popup) { 907 Drupal.eu_cookie_compliance.showWithdrawBanner(value); 908 } 909 }); 910 } 911 912 if (drupalSettings.eu_cookie_compliance.reload_page) { 913 var reloadRoutesList; 914 // Checks if there's any route on the settings. 915 if ((reloadRoutesList = drupalSettings.eu_cookie_compliance.reload_routes_list).length !== 0) { 916 var currentPath = drupalSettings.path.currentPath; 917 var match = false;
918 919 // If there are routes specified on the settings, it checks if any of 920 // it matches with the current path. 921 for (var n = 0; !match && n < reloadRoutesList.length; n++) { 922 var regExp = new RegExp(reloadRoutesList[n], "g"); 923 match = currentPath.match(regExp) !== null; 924 } 925 926 /* 927 * It will reload the page whether if the current path matches with one of the specified routes and the 928 * reload_options setting is set to "Include", which indicates that all matches should reload; OR if 929 * there's no match and the reload_options settings is set to "Exclude", which indicates that if the 930 * current path doesn't match with one of the specified routes, it should be reloaded. 931 */ 932 if ((match && !drupalSettings.eu_cookie_compliance.reload_options) || (!match && drupalSettings.eu_cookie_compliance.reload_options)) { 933 location.reload(); 934 } 935 } 936 // If no routes specified, then the page will be always reloaded. 937 else { 938 location.reload(); 939 } 940 } 941 942 Drupal.eu_cookie_compliance.setStatus(value); 943 }; 944 945 Drupal.eu_cookie_compliance.showWithdrawBanner = function (value) { 946 if (value === cookieValueAgreed && drupalSettings.eu_cookie_compliance.withdraw_enabled) { 947 if (!drupalSettings.eu_cookie_compliance.withdraw_button_on_info_popup) { 948 Drupal.eu_cookie_compliance.createWithdrawBanner(drupalSettings.eu_cookie_compliance.withdraw_markup); 949 Drupal.eu_cookie_compliance.resizeListener(); 950 } 951 Drupal.eu_cookie_compliance.attachWithdrawEvents(); 952 if (drupalSettings.eu_cookie_compliance.popup_position) { 953 Drupal.eu_cookie_compliance.positionTab(); 954 } 955 } 956 }; 957 958 Drupal.eu_cookie_compliance.setStatus = function (status) { 959 // Make a new observer & fire it to allow other scripts to hook in. 960 var preStatusSaveObject = new PreStatusSave(); 961 self.handleEvent('preStatusSave', preStatusSaveObject); 962 963 var date = new Date(); 964 var domain = drupalSettings.eu_cookie_compliance.domain ? drupalSettings.eu_cookie_compliance.domain : ''; 965 var path = drupalSettings.eu_cookie_compliance.domain_all_sites ? '/' : drupalSettings.path.baseUrl; 966 var cookieName = (typeof drupalSettings.eu_cookie_compliance.cookie_name === 'undefined' || drupalSettings.eu_cookie_compliance.cookie_name === '') ? 'cookie-agreed' : drupalSettings.eu_cookie_compliance.cookie_name; 967 if (path.length > 1) { 968 var pathEnd = path.length - 1; 969 if (path.lastIndexOf('/') === pathEnd) { 970 path = path.substring(0, pathEnd); 971 } 972 } 973 974 var cookie_session = parseInt(drupalSettings.eu_cookie_compliance.cookie_session); 975 if (cookie_session) { 976 cookies.set(cookieName, status, { path: path, domain: domain, sameSite: 'strict' }); 977 } 978 else { 979 var lifetime = parseInt(drupalSettings.eu_cookie_compliance.cookie_lifetime); 980 date.setDate(date.getDate() + lifetime); 981 cookies.set(cookieName, status, { expires: date, path: path, domain: domain, sameSite: 'strict' }); 982 } 983 984 var currentStatusClass = 'eu-cookie-compliance-status-' + _euccCurrentStatus; 985 var nextStatusClass = 'eu-cookie-compliance-status-' + status; 986 $('.' + currentStatusClass).removeClass(currentStatusClass).addClass(nextStatusClass) 987 988 _euccCurrentStatus = status; 989 $(document).trigger('eu_cookie_compliance.changeStatus', [status]); 990 // Status set means something happened, update the version. 991 Drupal.eu_cookie_compliance.setVersion(); 992 993 // Store consent if applicable. 994 if (drupalSettings.eu_cookie_compliance.store_consent && ((status === cookieValueAgreedShowThankYou && drupalSettings.eu_cookie_compliance.popup_agreed_enabled) || (status === cookieValueAgreed && !drupalSettings.eu_cookie_compliance.popup_agreed_enabled))) { 995 var url = drupalSettings.path.baseUrl + drupalSettings.path.pathPrefix + 'eu-cookie-compliance/store_consent/banner'; 996 $.post(url, {}, function (data) { }); 997 } 998 999 // Make a new observer & fire it to allow other scripts to hook in. 1000 var postStatusSaveObject = new PostStatusSave(); 1001 self.handleEvent('postStatusSave', postStatusSaveObject); 1002 1003 if (status === cookieValueDisagreed && drupalSettings.eu_cookie_compliance.method === 'opt_out') { 1004 euCookieComplianceBlockCookies = setInterval(Drupal.eu_cookie_compliance.BlockCookies, 5000); 1005 } 1006 }; 1007 1008 Drupal.eu_cookie_compliance.setAcceptedCategories = function (categories) { 1009 // Make a new observer & fire it to allow other scripts to hook in. 1010 var prePreferencesSaveObject = new PrePreferencesSave(); 1011 self.handleEvent('prePreferencesSave', prePreferencesSaveObject); 1012 1013 var date = new Date(); 1014 var domain = drupalSettings.eu_cookie_compliance.domain ? drupalSettings.eu_cookie_compliance.domain : ''; 1015 var path = drupalSettings.eu_cookie_compliance.domain_all_sites ? '/' : drupalSettings.path.baseUrl; 1016 var cookieName = (typeof drupalSettings.eu_cookie_compliance.cookie_name === 'undefined' || drupalSettings.eu_cookie_compliance.cookie_name === '') ? 'cookie-agreed-categories' : drupalSettings.eu_cookie_compliance.cookie_name + '-categories'; 1017 if (path.length > 1) { 1018 var pathEnd = path.length - 1; 1019 if (path.lastIndexOf('/') === pathEnd) { 1020 path = path.substring(0, pathEnd); 1021 } 1022 } 1023 var categoriesString = JSON.stringify(categories); 1024 var cookie_session = parseInt(drupalSettings.eu_cookie_compliance.cookie_session); 1025 if (cookie_session) { 1026 cookies.set(cookieName, categoriesString, { path: path, domain: domain, sameSite: 'strict' }); 1027 } 1028 else { 1029 var lifetime = parseInt(drupalSettings.eu_cookie_compliance.cookie_lifetime); 1030 date.setDate(date.getDate() + lifetime); 1031 cookies.set(cookieName, categoriesString, { expires: date, path: path, domain: domain, sameSite: 'strict' }); 1032 } 1033 _euccSelectedCategories = categories; 1034 $(document).trigger('eu_cookie_compliance.changePreferences', [categories]); 1035 1036 // TODO: Store categories with consent if applicable? 1037 // Make a new observer & fire it to allow other scripts to hook in. 1038 var postPreferencesSaveObject = new PostPreferencesSave(); 1039 self.handleEvent('postPreferencesSave', postPreferencesSaveObject); 1040 }; 1041 1042 Drupal.eu_cookie_compliance.hasAgreed = function (category) {
1043 var agreed = (_euccCurrentStatus === cookieValueAgreedShowThankYou || _euccCurrentStatus === cookieValueAgreed); 1044 1045 if (category !== undefined && agreed && drupalSettings.eu_cookie_compliance.method === 'categories') { 1046 agreed = Drupal.eu_cookie_compliance.hasAgreedWithCategory(category); 1047 } 1048 1049 return agreed; 1050 }; 1051 1052 Drupal.eu_cookie_compliance.hasAgreedWithCategory = function (category) { 1053 return $.inArray(category, _euccSelectedCategories) !== -1; 1054 }; 1055 1056 Drupal.eu_cookie_compliance.showBanner = function () { 1057 var showBanner = false; 1058 if ((_euccCurrentStatus === cookieValueDisagreed && drupalSettings.eu_cookie_compliance.method === 'default') || _euccCurrentStatus === null) { 1059 if (!drupalSettings.eu_cookie_compliance.disagree_do_not_show_popup || _euccCurrentStatus === null) { 1060 showBanner = true; 1061 } 1062 } 1063 else if (_euccCurrentStatus === cookieValueAgreedShowThankYou && drupalSettings.eu_cookie_compliance.popup_agreed_enabled) { 1064 showBanner = true; 1065 } 1066 else if (_euccCurrentStatus === cookieValueAgreed && drupalSettings.eu_cookie_compliance.withdraw_enabled) { 1067 showBanner = true; 1068 } 1069 1070 return showBanner; 1071 }; 1072 1073 Drupal.eu_cookie_compliance.cookiesEnabled = function () { 1074 var cookieEnabled = (navigator.cookieEnabled); 1075 if (typeof navigator.cookieEnabled === 'undefined' && !cookieEnabled) { 1076 cookies.set('testcookie', 'testcookie', { expires: 100, sameSite: 'strict' }); 1077 cookieEnabled = (cookies.get('testcookie').indexOf('testcookie') !== -1); 1078 } 1079 1080 return (cookieEnabled); 1081 }; 1082 1083 Drupal.eu_cookie_compliance.cookieMatches = function (cookieName, pattern) { 1084 if (cookieName === pattern) { 1085 return true; 1086 } 1087 if (pattern.indexOf('*') < 0) { 1088 return false; 1089 } 1090 try { 1091 var regexp = new RegExp('^' + pattern.replace(/\./g, '\\.').replace(/\*/g, '.+') + '$', 'g'); 1092 return regexp.test(cookieName); 1093 } 1094 catch (err) { 1095 return false; 1096 } 1097 }; 1098 1099 Drupal.eu_cookie_compliance.isAllowed = function (cookieName) { 1100 // Skip the PHP session cookie. 1101 if (cookieName.indexOf('SESS') === 0 || cookieName.indexOf('SSESS') === 0) { 1102 return true; 1103 } 1104 // Split the allowed cookies. 1105 var euCookieComplianceAllowlist = drupalSettings.eu_cookie_compliance.allowed_cookies.split(/\r\n|\n|\r/g); 1106 1107 // Add the EU Cookie Compliance cookie. 1108 euCookieComplianceAllowlist.push((typeof drupalSettings.eu_cookie_compliance.cookie_name === 'undefined' || drupalSettings.eu_cookie_compliance.cookie_name === '') ? 'cookie-agreed' : drupalSettings.eu_cookie_compliance.cookie_name); 1109 euCookieComplianceAllowlist.push((typeof drupalSettings.eu_cookie_compliance.cookie_name === 'undefined' || drupalSettings.eu_cookie_compliance.cookie_name === '') ? 'cookie-agreed-categories' : drupalSettings.eu_cookie_compliance.cookie_name + '-categories'); 1110 euCookieComplianceAllowlist.push((typeof drupalSettings.eu_cookie_compliance.cookie_name === 'undefined' || drupalSettings.eu_cookie_compliance.cookie_name === '') ? 'cookie-agreed-version' : drupalSettings.eu_cookie_compliance.cookie_name + '-version'); 1111 // Check if the cookie is allowed. 1112 for (var item in euCookieComplianceAllowlist) { 1113 // Defensively check types for comparison. 1114 if (typeof euCookieComplianceAllowlist[item] === "string") { 1115 if (Drupal.eu_cookie_compliance.cookieMatches(cookieName, euCookieComplianceAllowlist[item])) { 1116 return true; 1117 } 1118 // Handle cookie names that are prefixed with a category. 1119 if (drupalSettings.eu_cookie_compliance.method === 'categories') { 1120 var separatorPos = euCookieComplianceAllowlist[item].indexOf(":"); 1121 if (separatorPos !== -1) { 1122 var category = euCookieComplianceAllowlist[item].substr(0, separatorPos); 1123 var wlCookieName = euCookieComplianceAllowlist[item].substr(separatorPos + 1); 1124 1125 if (Drupal.eu_cookie_compliance.cookieMatches(cookieName, wlCookieName) && Drupal.eu_cookie_compliance.hasAgreedWithCategory(category)) { 1126 return true; 1127 } 1128 } 1129 } 1130 } 1131 } 1132 1133 return false;
1134 } 1135 1136 Drupal.eu_cookie_compliance.getVersion = function () { 1137 // Only get cookie-agreed-version version cookie, if user agreed. 1138 if (!Drupal.eu_cookie_compliance.hasAgreed()) { 1139 return false; 1140 } 1141 1142 var cookieName = (typeof drupalSettings.eu_cookie_compliance.cookie_name === 'undefined' || drupalSettings.eu_cookie_compliance.cookie_name === '') ? 'cookie-agreed-version' : drupalSettings.eu_cookie_compliance.cookie_name + '-version'; 1143 return cookies.get(cookieName); 1144 }; 1145 1146 Drupal.eu_cookie_compliance.setVersion = function (force_this_version) { 1147 // Only set cookie-agreed-version version cookie, if user agreed. 1148 if (!Drupal.eu_cookie_compliance.hasAgreed()) { 1149 return false; 1150 } 1151 1152 var date = new Date(); 1153 var domain = drupalSettings.eu_cookie_compliance.domain ? drupalSettings.eu_cookie_compliance.domain : ''; 1154 var path = drupalSettings.eu_cookie_compliance.domain_all_sites ? '/' : drupalSettings.path.baseUrl; 1155 var cookieName = (typeof drupalSettings.eu_cookie_compliance.cookie_name === 'undefined' || drupalSettings.eu_cookie_compliance.cookie_name === '') ? 'cookie-agreed-version' : drupalSettings.eu_cookie_compliance.cookie_name + '-version'; 1156 if (path.length > 1) { 1157 var pathEnd = path.length - 1; 1158 if (path.lastIndexOf('/') === pathEnd) { 1159 path = path.substring(0, pathEnd); 1160 } 1161 } 1162 1163 var eucc_version = (force_this_version !== undefined) ? force_this_version : drupalSettings.eu_cookie_compliance.cookie_policy_version; 1164 var cookie_session = parseInt(drupalSettings.eu_cookie_compliance.cookie_session); 1165 if (cookie_session) { 1166 cookies.set(cookieName, eucc_version, { path: path, domain: domain, sameSite: 'strict' }); 1167 } 1168 else { 1169 var lifetime = parseInt(drupalSettings.eu_cookie_compliance.cookie_lifetime); 1170 date.setDate(date.getDate() + lifetime); 1171 cookies.set(cookieName, eucc_version, { expires: date, path: path, domain: domain, sameSite: 'strict' }); 1172 } 1173 }; 1174 1175 // Load blocked scripts if the user has agreed to being tracked. 1176 var euCookieComplianceHasLoadedScripts = false; 1177 var euCookieComplianceHasLoadedScriptsForCategory = {}; 1178 $(function () { 1179 if (typeof drupalSettings.eu_cookie_compliance !== 'undefined') { 1180 if (Drupal.eu_cookie_compliance.hasAgreed() 1181 || (_euccCurrentStatus === null && drupalSettings.eu_cookie_compliance.method !== 'opt_in' && drupalSettings.eu_cookie_compliance.method !== 'categories') 1182 ) { 1183 if (typeof euCookieComplianceLoadScripts === "function") { 1184 euCookieComplianceLoadScripts(); 1185 } 1186 euCookieComplianceHasLoadedScripts = true; 1187 1188 if (drupalSettings.eu_cookie_compliance.method === 'categories') { 1189 Drupal.eu_cookie_compliance.loadCategoryScripts(_euccSelectedCategories); 1190 } 1191 } 1192 } 1193 }); 1194 1195 Drupal.eu_cookie_compliance.BlockCookies = function () { 1196 var cookieStatus = Drupal.eu_cookie_compliance.getCookieStatus(); 1197 if ((cookieStatus === cookieValueAgreedShowThankYou || cookieStatus === cookieValueAgreed) 1198 && drupalSettings.eu_cookie_compliance.method !== 'categories') { 1199 // Stop blocking the cookies if it's already been agreed to (e.g. in a different tab). 1200 if (typeof euCookieComplianceBlockCookies !== 'undefined') { 1201 clearInterval(euCookieComplianceBlockCookies); 1202 return; 1203 } 1204 } 1205 // Load all cookies from jQuery. 1206 var allCookies = cookies.get(); 1207 1208 // Check each cookie and try to remove it if it's not allowed. 1209 for (var i in allCookies) { 1210 var remove = true; 1211 var hostname = window.location.hostname; 1212 var cookieRemoved = false; 1213 var index = 0; 1214 1215 remove = !Drupal.eu_cookie_compliance.isAllowed(i); 1216 1217 // Remove the cookie if it's not allowed. 1218 if (remove) { 1219 while (!cookieRemoved && hostname !== '') { 1220 // Attempt to remove. 1221 cookies.remove(i, { domain: '.' + hostname, path: '/' }); 1222 cookieRemoved = !cookies.get(i); 1223 if (!cookieRemoved) { 1224 cookies.remove(i, { domain: hostname, path: '/' }); 1225 cookieRemoved = !cookies.get(i); 1226 } 1227 1228 index = hostname.indexOf('.'); 1229 1230 // We can be on a sub-domain, so keep checking the main domain as well. 1231 hostname = (index === -1) ? '' : hostname.substring(index + 1); 1232 } 1233 1234 // Some jQuery Cookie versions don't remove cookies well. Try again
1235 // using plain js. 1236 if (!cookieRemoved) { 1237 document.cookie = i + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/;'; 1238 } 1239 } 1240 } 1241 } 1242 1243 // Block cookies when the user hasn't agreed. 1244 if ((typeof drupalSettings.eu_cookie_compliance !== 'undefined') && 1245 drupalSettings.eu_cookie_compliance.automatic_cookies_removal && 1246 ( 1247 (drupalSettings.eu_cookie_compliance.method === 'opt_in' && (_euccCurrentStatus === null || !Drupal.eu_cookie_compliance.hasAgreed())) 1248 || (drupalSettings.eu_cookie_compliance.method === 'opt_out' && !Drupal.eu_cookie_compliance.hasAgreed() && _euccCurrentStatus !== null) 1249 || (drupalSettings.eu_cookie_compliance.method === 'categories') 1250 )) { 1251 euCookieComplianceBlockCookies = setInterval(Drupal.eu_cookie_compliance.BlockCookies, 5000); 1252 } 1253 1254 /** 1255 * Filter the event listeners by event name and return the list of handlers. 1256 * 1257 * @param forEventName 1258 * 1259 * @returns {[]} 1260 */ 1261 var filterQueue = function (forEventName) { 1262 var handlers = []; 1263 if (typeof Drupal.eu_cookie_compliance !== 'undefined' && 1264 typeof Drupal.eu_cookie_compliance.queue !== 'undefined' && 1265 Drupal.eu_cookie_compliance.queue.length) { 1266 // Loop over the list of arguments (objects) pushed into the queue. 1267 for (var i = 0; i < Drupal.eu_cookie_compliance.queue.length; i++) { 1268 if (Drupal.eu_cookie_compliance.queue[i].length) { 1269 var queueItem = Drupal.eu_cookie_compliance.queue[i]; 1270 var eventName = queueItem[0]; 1271 var eventHandler = queueItem[1]; 1272 // If the first element is a string and the second is a function. 1273 if (typeof eventName === 'string' && typeof eventHandler === 'function') { 1274 // And the string matches the event name. 1275 if (eventName === forEventName) { 1276 // Return the functions so they can be executed. 1277 handlers.push(eventHandler); 1278 } 1279 } 1280 } 1281 } 1282 } 1283 return handlers; 1284 } 1285 1286 /** 1287 * Handle event by finding and executing handlers pushed to the queue. 1288 */ 1289 self.handleEvent = function (eventName, observer) { 1290 var handlers = filterQueue(eventName); 1291 for (var i = 0; i < handlers.length; i++) { 1292 if (typeof handlers[i] !== 'undefined') { 1293 observer.subscribe(handlers[i]); 1294 observer.fire({ 1295 currentStatus: _euccCurrentStatus, 1296 currentCategories: _euccSelectedCategories 1297 }); 1298 observer.unsubscribe(handlers[i]); 1299 } 1300 } 1301 }; 1302 1303 /** 1304 * Observer: triggered before status gets read from cookie. 1305 */ 1306 var PreStatusLoad = (function () { 1307 // Constructor. 1308 var PreStatusLoad = function () { 1309 // Observers. 1310 this.handlers = []; 1311 }; 1312 // Convenience var for the prototype. 1313 var prototype = PreStatusLoad.prototype; 1314 prototype.subscribe = function (fn) { 1315 this.handlers.push(fn); 1316 }; 1317 prototype.unsubscribe = function (fn) { 1318 this.handlers = this.handlers.filter( 1319 function (item) { 1320 if (item !== fn) { 1321 return item; 1322 } 1323 } 1324 ); 1325 }; 1326 prototype.fire = function (o, thisObj) { 1327 var scope = thisObj || window; 1328 this.handlers.forEach(function (item) { 1329 item.call(scope, o); 1330 }); 1331 }; 1332 return PreStatusLoad; 1333 })(); 1334 1335 /** 1336 * Observer: when status was read from cookie and stored in private variable. 1337 */ 1338 var PostStatusLoad = (function () { 1339 // Constructor. 1340 var PostStatusLoad = function () { 1341 // Observers. 1342 this.handlers = []; 1343 }; 1344 // Convenience var for the prototype. 1345 var prototype = PostStatusLoad.prototype; 1346 prototype.subscribe = function (fn) { 1347 this.handlers.push(fn); 1348 }; 1349 prototype.unsubscribe = function (fn) { 1350 this.handlers = this.handlers.filter( 1351 function (item) { 1352 if (item !== fn) { 1353 return item; 1354 } 1355 } 1356 ); 1357 }; 1358 prototype.fire = function (o, thisObj) { 1359 var scope = thisObj || window; 1360 this.handlers.forEach(function (item) { 1361 item.call(scope, o); 1362 }); 1363 }; 1364 return PostStatusLoad; 1365 })(); 1366 1367 /** 1368 * Observer: triggered before status gets saved into cookie. 1369 */ 1370 var PreStatusSave = (function () { 1371 // Constructor. 1372 var PreStatusSave = function () { 1373 // Observers. 1374 this.handlers = []; 1375 }; 1376 // Convenience var for the prototype. 1377 var prototype = PreStatusSave.prototype; 1378 prototype.subscribe = function (fn) { 1379 this.handlers.push(fn); 1380 }; 1381 prototype.unsubscribe = function (fn) { 1382 this.handlers = this.handlers.filter( 1383 function (item) { 1384 if (item !== fn) { 1385 return item; 1386 } 1387 } 1388 ); 1389 }; 1390 prototype.fire = function (o, thisObj) { 1391 var scope = thisObj || window;
1392 this.handlers.forEach(function (item) { 1393 item.call(scope, o); 1394 }); 1395 }; 1396 return PreStatusSave; 1397 })(); 1398 1399 /** 1400 * Observer: triggered after status was saved into cookie. 1401 */ 1402 var PostStatusSave = (function () { 1403 // Constructor. 1404 var PostStatusSave = function () { 1405 // Observers. 1406 this.handlers = []; 1407 }; 1408 // Convenience var for the prototype. 1409 var prototype = PostStatusSave.prototype; 1410 prototype.subscribe = function (fn) { 1411 this.handlers.push(fn); 1412 }; 1413 prototype.unsubscribe = function (fn) { 1414 this.handlers = this.handlers.filter( 1415 function (item) { 1416 if (item !== fn) { 1417 return item; 1418 } 1419 } 1420 ); 1421 }; 1422 prototype.fire = function (o, thisObj) { 1423 var scope = thisObj || window; 1424 this.handlers.forEach(function (item) { 1425 item.call(scope, o); 1426 }); 1427 }; 1428 return PostStatusSave; 1429 })(); 1430 1431 /** 1432 * Observer: triggered before categories are read from cookie. 1433 */ 1434 var PrePreferencesLoad = (function () { 1435 // Constructor. 1436 var prePreferencesLoad = function () { 1437 // Observers. 1438 this.handlers = []; 1439 }; 1440 // Convenience var for the prototype. 1441 var prototype = prePreferencesLoad.prototype; 1442 prototype.subscribe = function (fn) { 1443 this.handlers.push(fn); 1444 }; 1445 prototype.unsubscribe = function (fn) { 1446 this.handlers = this.handlers.filter( 1447 function (item) { 1448 if (item !== fn) { 1449 return item; 1450 } 1451 } 1452 ); 1453 }; 1454 prototype.fire = function (o, thisObj) { 1455 var scope = thisObj || window; 1456 this.handlers.forEach(function (item) { 1457 item.call(scope, o); 1458 }); 1459 }; 1460 return prePreferencesLoad; 1461 })(); 1462 1463 /** 1464 * Observer: triggered after categories were read from cookie. 1465 */ 1466 var PostPreferencesLoad = (function () { 1467 // Constructor. 1468 var postPreferencesLoad = function () { 1469 // Observers. 1470 this.handlers = []; 1471 }; 1472 // Convenience var for the prototype. 1473 var prototype = postPreferencesLoad.prototype; 1474 prototype.subscribe = function (fn) { 1475 this.handlers.push(fn); 1476 }; 1477 prototype.unsubscribe = function (fn) { 1478 this.handlers = this.handlers.filter( 1479 function (item) { 1480 if (item !== fn) { 1481 return item; 1482 } 1483 } 1484 ); 1485 }; 1486 prototype.fire = function (o, thisObj) { 1487 var scope = thisObj || window; 1488 this.handlers.forEach(function (item) { 1489 item.call(scope, o); 1490 }); 1491 }; 1492 return postPreferencesLoad; 1493 })(); 1494 1495 /** 1496 * Observer: triggered before categories are being saved to cookie. 1497 */ 1498 var PrePreferencesSave = (function () { 1499 // Constructor. 1500 var prePreferencesSave = function () { 1501 // Observers. 1502 this.handlers = []; 1503 }; 1504 // Convenience var for the prototype. 1505 var prototype = prePreferencesSave.prototype; 1506 prototype.subscribe = function (fn) { 1507 this.handlers.push(fn); 1508 }; 1509 prototype.unsubscribe = function (fn) { 1510 this.handlers = this.handlers.filter( 1511 function (item) { 1512 if (item !== fn) { 1513 return item; 1514 } 1515 } 1516 ); 1517 }; 1518 prototype.fire = function (o, thisObj) { 1519 var scope = thisObj || window; 1520 this.handlers.forEach(function (item) { 1521 item.call(scope, o); 1522 }); 1523 }; 1524 return prePreferencesSave; 1525 })(); 1526 1527 /** 1528 * Observer: triggered after categories were saved to cookie. 1529 */ 1530 var PostPreferencesSave = (function () { 1531 // Constructor. 1532 var postPreferencesSave = function () { 1533 // Observers. 1534 this.handlers = []; 1535 }; 1536 // Convenience var for the prototype. 1537 var prototype = postPreferencesSave.prototype; 1538 prototype.subscribe = function (fn) { 1539 this.handlers.push(fn); 1540 }; 1541 prototype.unsubscribe = function (fn) { 1542 this.handlers = this.handlers.filter( 1543 function (item) { 1544 if (item !== fn) { 1545 return item; 1546 } 1547 } 1548 ); 1549 }; 1550 prototype.fire = function (o, thisObj) { 1551 var scope = thisObj || window;
1552 this.handlers.forEach(function (item) { 1553 item.call(scope, o); 1554 }); 1555 }; 1556 return postPreferencesSave; 1557 })(); 1558 1559})(jQuery, Drupal, drupalSettings, window.Cookies);
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.