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