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