1/** 2 * @file 3 * Cookie Compliance Javascript. 4 * 5 * Statuses: 6 * null: not yet agreed (or withdrawn), show popup 7 * 0: Disagreed 8 * 1: Agreed, show thank you banner 9 * 2: Agreed. 10 */ 11 12(function ($) { 13 14 'use strict'; 15 var euCookieComplianceBlockCookies; 16 var cookieValueDisagreed = (typeof Drupal.settings.eu_cookie_compliance.cookie_value_disagreed === 'undefined' || Drupal.settings.eu_cookie_compliance.cookie_value_disagreed === '') ? '0' : Drupal.settings.eu_cookie_compliance.cookie_value_disagreed; 17 var cookieValueAgreedShowThankYou = (typeof Drupal.settings.eu_cookie_compliance.cookie_value_agreed_show_thank_you === 'undefined' || Drupal.settings.eu_cookie_compliance.cookie_value_agreed_show_thank_you === '') ? '1' : Drupal.settings.eu_cookie_compliance.cookie_value_agreed_show_thank_you; 18 var cookieValueAgreed = (typeof Drupal.settings.eu_cookie_compliance.cookie_value_agreed === 'undefined' || Drupal.settings.eu_cookie_compliance.cookie_value_agreed === '') ? '2' : Drupal.settings.eu_cookie_compliance.cookie_value_agreed; 19 20 Drupal.behaviors.eu_cookie_compliance_popup = { 21 attach: function (context, settings) { 22 $(Drupal.settings.eu_cookie_compliance.containing_element, context).once('eu-cookie-compliance', function () { 23 24 // Initialize internal variables. 25 _euccCurrentStatus = self.getCurrentStatus(); 26 _euccSelectedCategories = self.getAcceptedCategories(); 27 28 // If configured, check JSON callback to determine if in EU. 29 if (Drupal.settings.eu_cookie_compliance.popup_eu_only_js) { 30 if (Drupal.eu_cookie_compliance.showBanner()) { 31 var url = Drupal.settings.basePath + Drupal.settings.pathPrefix + 'eu-cookie-compliance-check'; 32 var data = {}; 33 $.getJSON(url, data, function (data) { 34 // If in the EU, show the compliance banner. 35 if (data.in_eu) { 36 Drupal.eu_cookie_compliance.execute(); 37 } 38 39 // If not in EU, set an agreed cookie automatically. 40 else { 41 Drupal.eu_cookie_compliance.setStatus(cookieValueAgreed); 42 } 43 }); 44 } 45 } 46 47 // Otherwise, fallback to standard behavior which is to render the banner. 48 else { 49 Drupal.eu_cookie_compliance.execute(); 50 } 51 }).addClass('eu-cookie-compliance-status-' + Drupal.eu_cookie_compliance.getCurrentStatus()); 52 } 53 }; 54 55 // Sep up the namespace as a function to store list of arguments in a queue. 56 Drupal.eu_cookie_compliance = Drupal.eu_cookie_compliance || function () { 57 (Drupal.eu_cookie_compliance.queue = Drupal.eu_cookie_compliance.queue || []).push(arguments) 58 }; 59 // Initialize the object with some data. 60 Drupal.eu_cookie_compliance.a = +new Date; 61 // A shorter name to use when accessing the namespace. 62 var self = Drupal.eu_cookie_compliance; 63 // Save our cookie preferences locally only. 64 // Used by external scripts to modify data before it is used. 65 var _euccSelectedCategories = []; 66 var _euccCurrentStatus = null; 67 self.updateSelectedCategories = function (categories) { 68 _euccSelectedCategories = categories; 69 } 70 self.updateCurrentStatus = function (status) { 71 _euccCurrentStatus = status; 72 } 73 74 Drupal.eu_cookie_compliance.execute = function () { 75 try { 76 if (!Drupal.settings.eu_cookie_compliance.popup_enabled) { 77 return; 78 } 79 80 if (!Drupal.eu_cookie_compliance.cookiesEnabled()) { 81 return; 82 } 83 84 if (typeof Drupal.eu_cookie_compliance.getVersion() === 'undefined') { 85 // If version doesn't exist as a cookie, set it to the current one. 86 // For modules that update to this, it prevents needless retriggering 87 // For first time runs, it makes no difference as the other IF statements 88 // below will still cause the popup to trigger 89 // For incrementing the version, it also makes no difference as either it's
90 // a returning user and will have a version set, or it's a new user and 91 // the other checks will trigger it. 92 Drupal.eu_cookie_compliance.setVersion(); 93 } 94 95 Drupal.eu_cookie_compliance.updateCheck(); 96 var versionChanged = Drupal.eu_cookie_compliance.getVersion() !== Drupal.settings.eu_cookie_compliance.cookie_policy_version; 97 // Closed if status has a value and the version hasn't changed. 98 var closed = _euccCurrentStatus !== null && !versionChanged; 99 if ((_euccCurrentStatus === 0 && Drupal.settings.eu_cookie_compliance.method === 'default') || _euccCurrentStatus === null || (Drupal.settings.eu_cookie_compliance.withdraw_enabled && Drupal.settings.eu_cookie_compliance.withdraw_button_on_info_popup) || versionChanged) { 100 if (Drupal.settings.eu_cookie_compliance.withdraw_enabled || !Drupal.settings.eu_cookie_compliance.disagree_do_not_show_popup || _euccCurrentStatus === null || versionChanged) { 101 // Detect mobile here and use mobile_popup_html_info, if we have a mobile device. 102 if (window.matchMedia('(max-width: ' + Drupal.settings.eu_cookie_compliance.mobile_breakpoint + 'px)').matches && Drupal.settings.eu_cookie_compliance.use_mobile_message) { 103 Drupal.eu_cookie_compliance.createPopup(Drupal.settings.eu_cookie_compliance.mobile_popup_html_info, closed); 104 } 105 else { 106 Drupal.eu_cookie_compliance.createPopup(Drupal.settings.eu_cookie_compliance.popup_html_info, closed); 107 } 108 109 Drupal.eu_cookie_compliance.initPopup(); 110 Drupal.eu_cookie_compliance.resizeListener(); 111 } 112 } 113 if (_euccCurrentStatus === 1 && Drupal.settings.eu_cookie_compliance.popup_agreed_enabled) { 114 // Thank you banner. 115 Drupal.eu_cookie_compliance.createPopup(Drupal.settings.eu_cookie_compliance.popup_html_agreed); 116 Drupal.eu_cookie_compliance.attachHideEvents(); 117 } 118 else if (_euccCurrentStatus === 2 && Drupal.settings.eu_cookie_compliance.withdraw_enabled) { 119 if (!Drupal.settings.eu_cookie_compliance.withdraw_button_on_info_popup) { 120 Drupal.eu_cookie_compliance.createWithdrawBanner(Drupal.settings.eu_cookie_compliance.withdraw_markup); 121 Drupal.eu_cookie_compliance.resizeListener(); 122 } 123 Drupal.eu_cookie_compliance.attachWithdrawEvents(); 124 } 125 } 126 catch (e) { 127 } 128 }; 129 130 Drupal.eu_cookie_compliance.initPopup = function () { 131 Drupal.eu_cookie_compliance.attachAgreeEvents(); 132 133 if (Drupal.settings.eu_cookie_compliance.method === 'categories') { 134 Drupal.eu_cookie_compliance.setPreferenceCheckboxes(_euccSelectedCategories); 135 Drupal.eu_cookie_compliance.attachSavePreferencesEvents(); 136 } 137 138 if (Drupal.settings.eu_cookie_compliance.withdraw_enabled && Drupal.settings.eu_cookie_compliance.withdraw_button_on_info_popup) { 139 Drupal.eu_cookie_compliance.attachWithdrawEvents(); 140 if (_euccCurrentStatus === 1 || _euccCurrentStatus === 2) { 141 $('.eu-cookie-withdraw-button').removeClass('eu-cookie-compliance-hidden'); 142 } 143 } 144 } 145 146 Drupal.eu_cookie_compliance.positionTab = function () { 147 if (Drupal.settings.eu_cookie_compliance.popup_position) { 148 var totalHeight = $('.eu-cookie-withdraw-tab').outerHeight() + $('.eu-cookie-compliance-banner').outerHeight(); 149 $('.eu-cookie-withdraw-tab').css('margin-top', totalHeight + 'px'); 150 } 151 }; 152 153 Drupal.eu_cookie_compliance.createWithdrawBanner = function (html) { 154 var $html = $('<div></div>').html(html); 155 var $banner = $('.eu-cookie-withdraw-banner', $html); 156 $html.attr('id', 'sliding-popup'); 157 $html.addClass('eu-cookie-withdraw-wrapper'); 158 159 if (!Drupal.settings.eu_cookie_compliance.popup_use_bare_css) { 160 $banner.height(Drupal.settings.eu_cookie_compliance.popup_height) 161 .width(Drupal.settings.eu_cookie_compliance.popup_width); 162 } 163 $html.hide(); 164 var height = 0; 165 if (Drupal.settings.eu_cookie_compliance.popup_position) { 166 $html.prependTo(Drupal.settings.eu_cookie_compliance.containing_element); 167 height = $html.outerHeight(); 168 169 $html.show() 170 .addClass('sliding-popup-top') 171 .addClass('clearfix') 172 .css({ top: !Drupal.settings.eu_cookie_compliance.fixed_top_position ? -(parseInt($(Drupal.settings.eu_cookie_compliance.containing_element).css('padding-top')) + parseInt($(Drupal.settings.eu_cookie_compliance.containing_element).css('margin-top')) + height) : -1 * height });
173 // For some reason, the tab outerHeight is -10 if we don't use a timeout 174 // function to reveal the tab. 175 setTimeout(function () { 176 $html.animate({ top: !Drupal.settings.eu_cookie_compliance.fixed_top_position ? -(parseInt($(Drupal.settings.eu_cookie_compliance.containing_element).css('padding-top')) + parseInt($(Drupal.settings.eu_cookie_compliance.containing_element).css('margin-top')) + height) : -1 * height }, Drupal.settings.eu_cookie_compliance.popup_delay, null, function () { 177 $html.trigger('eu_cookie_compliance_popup_open'); 178 $('body').addClass('eu-cookie-compliance-popup-open'); 179 Drupal.eu_cookie_compliance.positionTab(); 180 }); 181 }.bind($html, height), 0); 182 } 183 else { 184 if (Drupal.settings.eu_cookie_compliance.better_support_for_screen_readers) { 185 $html.prependTo(Drupal.settings.eu_cookie_compliance.containing_element); 186 } 187 else { 188 $html.appendTo(Drupal.settings.eu_cookie_compliance.containing_element); 189 } 190 height = $html.outerHeight(); 191 $html.show() 192 .addClass('sliding-popup-bottom') 193 .css({ bottom: -1 * height }); 194 // For some reason, the tab outerHeight is -10 if we don't use a timeout 195 // function to reveal the tab. 196 setTimeout(function () { 197 $html.animate({ bottom: -1 * height }, Drupal.settings.eu_cookie_compliance.popup_delay, null, function () { 198 $html.trigger('eu_cookie_compliance_popup_open'); 199 $('body').addClass('eu-cookie-compliance-popup-open'); 200 }); 201 }.bind($html, height), 0); 202 } 203 }; 204 205 Drupal.eu_cookie_compliance.toggleWithdrawBanner = function () { 206 var $wrapper = $('#sliding-popup'); 207 var height = $wrapper.outerHeight(); 208 var $bannerIsShowing = ($wrapper.find('.eu-cookie-compliance-banner, .eu-cookie-withdraw-banner').is(':visible')); 209 if ($bannerIsShowing) { 210 $bannerIsShowing = Drupal.settings.eu_cookie_compliance.popup_position ? parseInt($wrapper.css('top')) === (!Drupal.settings.eu_cookie_compliance.fixed_top_position ? -(parseInt($(Drupal.settings.eu_cookie_compliance.containing_element).css('padding-top')) + parseInt($(Drupal.settings.eu_cookie_compliance.containing_element).css('margin-top'))) : 0) : parseInt($wrapper.css('bottom')) === 0; 211 } 212 if (Drupal.settings.eu_cookie_compliance.popup_position) { 213 if ($bannerIsShowing) { 214 $wrapper.animate({ top: !Drupal.settings.eu_cookie_compliance.fixed_top_position ? -(parseInt($(Drupal.settings.eu_cookie_compliance.containing_element).css('padding-top')) + parseInt($(Drupal.settings.eu_cookie_compliance.containing_element).css('margin-top')) + height) : -1 * height }, Drupal.settings.eu_cookie_compliance.popup_delay).trigger('eu_cookie_compliance_popup_close'); 215 $('body').removeClass('eu-cookie-compliance-popup-open'); 216 } 217 else { 218 // If "Do not show cookie policy when the user clicks the Cookie policy button." is 219 // selected, the inner banner may be hidden. 220 $wrapper.find('.eu-cookie-compliance-banner').show(); 221 $wrapper.animate({ top: !Drupal.settings.eu_cookie_compliance.fixed_top_position ? -(parseInt($(Drupal.settings.eu_cookie_compliance.containing_element).css('padding-top')) + parseInt($(Drupal.settings.eu_cookie_compliance.containing_element).css('margin-top'))) : 0 }, Drupal.settings.eu_cookie_compliance.popup_delay).trigger('eu_cookie_compliance_popup_open'); 222 $('body').addClass('eu-cookie-compliance-popup-open'); 223 } 224 } 225 else { 226 if ($bannerIsShowing) { 227 $wrapper.animate({ 'bottom': -1 * height }, Drupal.settings.eu_cookie_compliance.popup_delay).trigger('eu_cookie_compliance_popup_close'); 228 $('body').removeClass('eu-cookie-compliance-popup-open'); 229 } 230 else { 231 // If "Do not show cookie policy when the user clicks the Cookie policy button." is 232 // selected, the inner banner may be hidden. 233 $wrapper.find('.eu-cookie-compliance-banner').show(); 234 $wrapper.animate({ 'bottom': 0 }, Drupal.settings.eu_cookie_compliance.popup_delay).trigger('eu_cookie_compliance_popup_open'); 235 $('body').addClass('eu-cookie-compliance-popup-open'); 236 } 237 } 238 }; 239 240 Drupal.eu_cookie_compliance.resizeListener = function () { 241 var $wrapper = $('#sliding-popup'); 242 243 const debounce = function (func, wait ) { 244 var timeout; 245
246 return function executedFunction() { 247 var later = function () { 248 clearTimeout(timeout); 249 func(); 250 }; 251 252 clearTimeout(timeout); 253 timeout = setTimeout(later, wait); 254 }; 255 }; 256 257 var checkIfPopupIsClosed = debounce(function () { 258 var wrapperHeight = $wrapper.outerHeight(); 259 if (Drupal.settings.eu_cookie_compliance.popup_position) { 260 var wrapperTopProperty = parseFloat($wrapper.css('bottom')); 261 if (wrapperTopProperty !== 0) { 262 $wrapper.css('top', wrapperHeight * -1); 263 } 264 } 265 else { 266 var wrapperBottomProperty = parseFloat($wrapper.css('bottom')); 267 if (wrapperBottomProperty !== 0) { 268 $wrapper.css('bottom', wrapperHeight * -1); 269 } 270 } 271 }, 50); 272 273 setTimeout(function () { 274 checkIfPopupIsClosed(); 275 }); 276 277 window.addEventListener('resize', checkIfPopupIsClosed); 278 279 }; 280 281 Drupal.eu_cookie_compliance.createPopup = function (html, closed) { 282 // This fixes a problem with jQuery 1.9. 283 var $popup = $('<div></div>').html(html); 284 $popup.attr('id', 'sliding-popup'); 285 if (!Drupal.settings.eu_cookie_compliance.popup_use_bare_css) { 286 $popup.height(Drupal.settings.eu_cookie_compliance.popup_height) 287 .width(Drupal.settings.eu_cookie_compliance.popup_width); 288 } 289 290 $popup.hide(); 291 var height = 0; 292 if (Drupal.settings.eu_cookie_compliance.popup_position) { 293 $popup.prependTo(Drupal.settings.eu_cookie_compliance.containing_element); 294 height = $popup.outerHeight(); 295 $popup.show() 296 .attr({ 'class': 'sliding-popup-top clearfix' }) 297 .css({ top: !Drupal.settings.eu_cookie_compliance.fixed_top_position ? -(parseInt($(Drupal.settings.eu_cookie_compliance.containing_element).css('padding-top')) + parseInt($(Drupal.settings.eu_cookie_compliance.containing_element).css('margin-top')) + height) : -1 * height }); 298 if (closed !== true) { 299 $popup.animate({ top: !Drupal.settings.eu_cookie_compliance.fixed_top_position ? -(parseInt($(Drupal.settings.eu_cookie_compliance.containing_element).css('padding-top')) + parseInt($(Drupal.settings.eu_cookie_compliance.containing_element).css('margin-top'))) : 0 }, Drupal.settings.eu_cookie_compliance.popup_delay, null, function () { 300 $popup.trigger('eu_cookie_compliance_popup_open'); 301 $('body').addClass('eu-cookie-compliance-popup-open'); 302 Drupal.eu_cookie_compliance.positionTab(); 303 }); 304 } 305 else { 306 setTimeout(function () { 307 Drupal.eu_cookie_compliance.positionTab(); 308 }, 0); 309 } 310 } 311 else { 312 if (Drupal.settings.eu_cookie_compliance.better_support_for_screen_readers) { 313 $popup.prependTo(Drupal.settings.eu_cookie_compliance.containing_element); 314 } 315 else { 316 $popup.appendTo(Drupal.settings.eu_cookie_compliance.containing_element); 317 } 318 319 height = $popup.outerHeight(); 320 $popup.show() 321 .attr({ 'class': 'sliding-popup-bottom' }) 322 .css({ bottom: -1 * height }); 323 if (closed !== true) { 324 $popup.animate({bottom: 0}, Drupal.settings.eu_cookie_compliance.popup_delay, null, function () { 325 $popup.trigger('eu_cookie_compliance_popup_open'); 326 $('body').addClass('eu-cookie-compliance-popup-open'); 327 }); 328 } 329 } 330 }; 331 332 Drupal.eu_cookie_compliance.attachAgreeEvents = function () { 333 var clickingConfirms = Drupal.settings.eu_cookie_compliance.popup_clicking_confirmation; 334 var scrollConfirms = Drupal.settings.eu_cookie_compliance.popup_scrolling_confirmation; 335 336 if (Drupal.settings.eu_cookie_compliance.method === 'categories' && Drupal.settings.eu_cookie_compliance.enable_save_preferences_button) { 337 // The agree button becomes an agree to all categories button when the 'save preferences' button is present. 338 $('.agree-button').click(Drupal.eu_cookie_compliance.acceptAllAction); 339 } 340 else { 341 $('.agree-button').click(Drupal.eu_cookie_compliance.acceptAction); 342 } 343 $('.decline-button').click(Drupal.eu_cookie_compliance.declineAction); 344 345 if (clickingConfirms) { 346 $('a, input[type=submit], button[type=submit]').not('.popup-content *').bind('click.euCookieCompliance', Drupal.eu_cookie_compliance.acceptAction); 347 } 348 349 if (scrollConfirms) { 350 var alreadyScrolled = false; 351 var scrollHandler = function () { 352 if (alreadyScrolled) { 353 Drupal.eu_cookie_compliance.acceptAction(); 354 $(window).off('scroll', scrollHandler); 355 } 356 else { 357 alreadyScrolled = true; 358 } 359 }; 360 361 $(window).bind('scroll', scrollHandler); 362 } 363 364 $('.find-more-button').not('.find-more-button-processed').addClass('find-more-button-processed').click(Drupal.eu_cookie_compliance.moreInfoAction); 365 }; 366 367 Drupal.eu_cookie_compliance.attachSavePreferencesEvents = function () { 368 $('.eu-cookie-compliance-save-preferences-button').click(Drupal.eu_cookie_compliance.savePreferencesAction); 369 }; 370 371 Drupal.eu_cookie_compliance.attachHideEvents = function () { 372 var popupHideAgreed = Drupal.settings.eu_cookie_compliance.popup_hide_agreed; 373 var clickingConfirms = Drupal.settings.eu_cookie_compliance.popup_clicking_confirmation; 374 $('.hide-popup-button').click(function () { 375 Drupal.eu_cookie_compliance.changeStatus(cookieValueAgreed); 376 } 377 ); 378 if (clickingConfirms) { 379 $('a, input[type=submit], button[type=submit]').unbind('click.euCookieCompliance'); 380 } 381 382 if (popupHideAgreed) { 383 $('a, input[type=submit], button[type=submit]').bind('click.euCookieComplianceHideAgreed', function () { 384 Drupal.eu_cookie_compliance.changeStatus(cookieValueAgreed); 385 }); 386 } 387 388 $('.find-more-button').not('.find-more-button-processed').addClass('find-more-button-processed').click(Drupal.eu_cookie_compliance.moreInfoAction); 389 }; 390 391 Drupal.eu_cookie_compliance.attachWithdrawEvents = function () { 392 $('.eu-cookie-withdraw-button').click(Drupal.eu_cookie_compliance.withdrawAction); 393 $('.eu-cookie-withdraw-tab').click(Drupal.eu_cookie_compliance.toggleWithdrawBanner); 394 }; 395 396 Drupal.eu_cookie_compliance.acceptAction = function () { 397 var agreedEnabled = Drupal.settings.eu_cookie_compliance.popup_agreed_enabled;
398 var nextStatus = cookieValueAgreedShowThankYou; 399 if (!agreedEnabled) { 400 Drupal.eu_cookie_compliance.setStatus(cookieValueAgreedShowThankYou); 401 nextStatus = cookieValueAgreed; 402 } 403 404 if (!euCookieComplianceHasLoadedScripts && typeof euCookieComplianceLoadScripts === "function") { 405 euCookieComplianceLoadScripts(); 406 } 407 408 if (typeof euCookieComplianceBlockCookies !== 'undefined') { 409 clearInterval(euCookieComplianceBlockCookies); 410 } 411 412 if (Drupal.settings.eu_cookie_compliance.method === 'categories') { 413 // Select Checked categories. 414 var categories = $("#eu-cookie-compliance-categories input:checkbox:checked").map(function () { 415 return $(this).val(); 416 }).get(); 417 Drupal.eu_cookie_compliance.setAcceptedCategories(categories); 418 // Load scripts for all categories. If no categories selected, none 419 // will be loaded. 420 Drupal.eu_cookie_compliance.loadCategoryScripts(categories); 421 if (!categories.length) { 422 // No categories selected is the same as declining all cookies. 423 nextStatus = cookieValueDisagreed; 424 } 425 } 426 427 Drupal.eu_cookie_compliance.changeStatus(nextStatus); 428 429 if (Drupal.settings.eu_cookie_compliance.withdraw_enabled && Drupal.settings.eu_cookie_compliance.withdraw_button_on_info_popup) { 430 Drupal.eu_cookie_compliance.attachWithdrawEvents(); 431 if (_euccCurrentStatus === 1 || _euccCurrentStatus === 2) { 432 $('.eu-cookie-withdraw-button').removeClass('eu-cookie-compliance-hidden'); 433 } 434 } 435 }; 436 437 Drupal.eu_cookie_compliance.acceptAllAction = function () { 438 var allCategories = Drupal.settings.eu_cookie_compliance.cookie_categories; 439 Drupal.eu_cookie_compliance.setPreferenceCheckboxes(allCategories); 440 Drupal.eu_cookie_compliance.acceptAction(); 441 } 442 443 Drupal.eu_cookie_compliance.savePreferencesAction = function () { 444 var categories = $("#eu-cookie-compliance-categories input:checkbox:checked").map(function () { 445 return $(this).val(); 446 }).get(); 447 var agreedEnabled = Drupal.settings.eu_cookie_compliance.popup_agreed_enabled; 448 var nextStatus = cookieValueAgreedShowThankYou; 449 if (!agreedEnabled) { 450 Drupal.eu_cookie_compliance.setStatus(cookieValueAgreedShowThankYou); 451 nextStatus = cookieValueAgreed; 452 } 453 454 Drupal.eu_cookie_compliance.setAcceptedCategories(categories); 455 // Load scripts for all categories. If no categories selected, none 456 // will be loaded. 457 Drupal.eu_cookie_compliance.loadCategoryScripts(categories); 458 if (!categories.length) { 459 // No categories selected is the same as declining all cookies. 460 nextStatus = cookieValueDisagreed; 461 } 462 Drupal.eu_cookie_compliance.changeStatus(nextStatus); 463 }; 464 465 Drupal.eu_cookie_compliance.loadCategoryScripts = function (categories) { 466 for (var cat in categories) { 467 if (euCookieComplianceHasLoadedScriptsForCategory[cat] !== true && typeof euCookieComplianceLoadScripts === "function") { 468 euCookieComplianceLoadScripts(categories[cat]); 469 euCookieComplianceHasLoadedScriptsForCategory[cat] = true; 470 } 471 } 472 } 473 474 Drupal.eu_cookie_compliance.declineAction = function () { 475 Drupal.eu_cookie_compliance.setStatus(cookieValueDisagreed); 476 var popup = $('#sliding-popup'); 477 if (popup.hasClass('sliding-popup-top')) { 478 popup.animate({ top: !Drupal.settings.eu_cookie_compliance.fixed_top_position ? -(parseInt($(Drupal.settings.eu_cookie_compliance.containing_element).css('padding-top')) + parseInt($(Drupal.settings.eu_cookie_compliance.containing_element).css('margin-top')) + popup.outerHeight()) : popup.outerHeight() * -1 }, Drupal.settings.eu_cookie_compliance.popup_delay, null, function () { 479 popup.hide(); 480 }).trigger('eu_cookie_compliance_popup_close'); 481 $('body').removeClass('eu-cookie-compliance-popup-open'); 482 } 483 else { 484 popup.animate({ bottom: popup.outerHeight() * -1 }, Drupal.settings.eu_cookie_compliance.popup_delay, null, function () { 485 popup.hide(); 486 }).trigger('eu_cookie_compliance_popup_close'); 487 $('body').removeClass('eu-cookie-compliance-popup-open'); 488 } 489 }; 490 491 Drupal.eu_cookie_compliance.withdrawAction = function () { 492 // Save "decline". 493 Drupal.eu_cookie_compliance.setStatus(0); 494 495 Drupal.eu_cookie_compliance.setAcceptedCategories([]); 496 location.reload(); 497 }; 498 499 Drupal.eu_cookie_compliance.moreInfoAction = function () { 500 if (Drupal.settings.eu_cookie_compliance.disagree_do_not_show_popup) { 501 Drupal.eu_cookie_compliance.setStatus(cookieValueDisagreed); 502 if (Drupal.settings.eu_cookie_compliance.withdraw_enabled && Drupal.settings.eu_cookie_compliance.withdraw_button_on_info_popup) { 503 $('#sliding-popup .eu-cookie-compliance-banner').trigger('eu_cookie_compliance_popup_close').hide(); 504 $('body').removeClass('eu-cookie-compliance-popup-open'); 505 } 506 else { 507 $('#sliding-popup').trigger('eu_cookie_compliance_popup_close').remove(); 508 $('body').removeClass('eu-cookie-compliance-popup-open'); 509 } 510 } 511 else { 512 if (Drupal.settings.eu_cookie_compliance.popup_link_new_window) { 513 window.open(Drupal.settings.eu_cookie_compliance.popup_link); 514 } 515 else { 516 window.location.href = Drupal.settings.eu_cookie_compliance.popup_link; 517 } 518 } 519 }; 520 521 Drupal.eu_cookie_compliance.getCurrentStatus = function () { 522 // Make a new observer & fire it to allow other scripts to hook in. 523 var preStatusLoadObject = new PreStatusLoad(); 524 self.handleEvent('preStatusLoad', preStatusLoadObject); 525 526 var cookieName = (typeof eu_cookie_compliance_cookie_name === 'undefined' || eu_cookie_compliance_cookie_name === '') ? 'cookie-agreed' : eu_cookie_compliance_cookie_name; 527 if ($.cookie(cookieName) === cookieValueDisagreed) { 528 var numericalStatus = '0'; 529 }
529 else if ($.cookie(cookieName) === cookieValueAgreedShowThankYou) { 530 var numericalStatus = '1'; 531 } else if ($.cookie(cookieName) === cookieValueAgreed) { 532 var numericalStatus = '2'; 533 } 534 var storedStatus = numericalStatus; 535 _euccCurrentStatus = parseInt(storedStatus); 536 if (isNaN(_euccCurrentStatus)) { 537 _euccCurrentStatus = null; 538 } 539 540 // Make a new observer & fire it to allow other scripts to hook in. 541 var postStatusLoadObject = new PostStatusLoad(); 542 self.handleEvent('postStatusLoad', postStatusLoadObject); 543 544 return _euccCurrentStatus; 545 }; 546 547 Drupal.eu_cookie_compliance.setPreferenceCheckboxes = function (categories) { 548 // Unset all categories to prevent a problem where the checkboxes with a 549 // default state set would always show up as checked. 550 if ((categories.length && Drupal.eu_cookie_compliance.getCurrentStatus() !== null) || Drupal.eu_cookie_compliance.getCurrentStatus() === 0) { 551 $("#eu-cookie-compliance-categories input:checkbox").removeAttr("checked"); 552 } 553 // Check the appropriate checkboxes. 554 for (var i in categories) { 555 // Rewrite the id like we do in Drupal 7 drupal_html_class. 556 var safeCategoryId = categories[i].replace(/[ _\/\[\]]/g,'-').toLowerCase(); 557 var categoryElement = document.getElementById('cookie-category-' + safeCategoryId); 558 if (categoryElement !== null) { 559 categoryElement.checked = true; 560 } 561 } 562 } 563 564 Drupal.eu_cookie_compliance.getAcceptedCategories = function () { 565 // Make a new observer & fire it to allow other scripts to hook in. 566 var prePreferencesLoadObject = new PrePreferencesLoad(); 567 self.handleEvent('prePreferencesLoad', prePreferencesLoadObject); 568 569 var cookieName = (typeof eu_cookie_compliance_cookie_name === 'undefined' || eu_cookie_compliance_cookie_name === '') ? 'cookie-agreed-categories' : Drupal.settings.eu_cookie_compliance.cookie_name + '-categories'; 570 var storedCategories = $.cookie(cookieName); 571 572 if (storedCategories !== null && typeof storedCategories !== 'undefined') { 573 _euccSelectedCategories = JSON.parse(storedCategories); 574 } 575 else { 576 _euccSelectedCategories = []; 577 } 578 579 // Merge in required categories if not already present. Mimics old 580 // logic where "fix first category" changed logic in 581 // .hasAgreedWithCategory and this function. 582 for (var _categoryName in Drupal.settings.eu_cookie_compliance.cookie_categories_details) { 583 var _category = Drupal.settings.eu_cookie_compliance.cookie_categories_details[_categoryName]; 584 if (_category.checkbox_default_state === 'required' && $.inArray(_category.machine_name, _euccSelectedCategories) === -1) { 585 _euccSelectedCategories.push(_category.machine_name); 586 } 587 } 588 589 // Make a new observer & fire it to allow other scripts to hook in. 590 var postPreferencesLoadObject = new PostPreferencesLoad(); 591 self.handleEvent('postPreferencesLoad', postPreferencesLoadObject); 592 593 return _euccSelectedCategories; 594 }; 595 596 Drupal.eu_cookie_compliance.changeStatus = function (value) { 597 var reloadPage = Drupal.settings.eu_cookie_compliance.reload_page; 598 var previousState = _euccCurrentStatus; 599 if (_euccCurrentStatus === parseInt(value)) { 600 return; 601 } 602 603 if (Drupal.settings.eu_cookie_compliance.popup_position) { 604 $('.sliding-popup-top').animate({ top: !Drupal.settings.eu_cookie_compliance.fixed_top_position ? -(parseInt($(Drupal.settings.eu_cookie_compliance.containing_element).css('padding-top')) + parseInt($(Drupal.settings.eu_cookie_compliance.containing_element).css('margin-top')) + $('#sliding-popup').outerHeight()) : $('#sliding-popup').outerHeight() * -1 }, Drupal.settings.eu_cookie_compliance.popup_delay, function () { 605 if (value === cookieValueAgreedShowThankYou && previousState === null && !reloadPage) { 606 $('.sliding-popup-top').not('.eu-cookie-withdraw-wrapper').html(Drupal.settings.eu_cookie_compliance.popup_html_agreed).animate({ top: !Drupal.settings.eu_cookie_compliance.fixed_top_position ? -(parseInt($(Drupal.settings.eu_cookie_compliance.containing_element).css('padding-top')) + parseInt($(Drupal.settings.eu_cookie_compliance.containing_element).css('margin-top'))) : 0 }, Drupal.settings.eu_cookie_compliance.popup_delay); 607 Drupal.eu_cookie_compliance.attachHideEvents(); 608 }
609 else if (previousState === cookieValueAgreedShowThankYou) { 610 if (Drupal.settings.eu_cookie_compliance.withdraw_enabled && Drupal.settings.eu_cookie_compliance.withdraw_button_on_info_popup) { 611 // Restore popup content. 612 if (window.matchMedia('(max-width: ' + Drupal.settings.eu_cookie_compliance.mobile_breakpoint + 'px)').matches && Drupal.settings.eu_cookie_compliance.use_mobile_message) { 613 $('.sliding-popup-top').not('.eu-cookie-withdraw-wrapper').html(Drupal.settings.eu_cookie_compliance.mobile_popup_html_info); 614 } 615 else { 616 $('.sliding-popup-top').not('.eu-cookie-withdraw-wrapper').html(Drupal.settings.eu_cookie_compliance.popup_html_info); 617 } 618 Drupal.eu_cookie_compliance.initPopup(); 619 Drupal.eu_cookie_compliance.resizeListener(); 620 } 621 else { 622 $('.sliding-popup-top').not('.eu-cookie-withdraw-wrapper').trigger('eu_cookie_compliance_popup_close').remove(); 623 $('body').removeClass('eu-cookie-compliance-popup-open'); 624 } 625 } 626 if (Drupal.settings.eu_cookie_compliance.withdraw_enabled) { 627 Drupal.eu_cookie_compliance.showWithdrawBanner(value); 628 } 629 }); 630 } 631 else { 632 $('.sliding-popup-bottom').animate({ bottom: $('#sliding-popup').outerHeight() * -1 }, Drupal.settings.eu_cookie_compliance.popup_delay, function () { 633 if (value === cookieValueAgreedShowThankYou && previousState === null && !reloadPage) { 634 $('.sliding-popup-bottom').not('.eu-cookie-withdraw-wrapper').html(Drupal.settings.eu_cookie_compliance.popup_html_agreed).animate({ bottom: 0 }, Drupal.settings.eu_cookie_compliance.popup_delay); 635 Drupal.eu_cookie_compliance.attachHideEvents(); 636 } 637 else if (previousState === cookieValueAgreedShowThankYou) { 638 if (Drupal.settings.eu_cookie_compliance.withdraw_enabled && Drupal.settings.eu_cookie_compliance.withdraw_button_on_info_popup) { 639 // Restore popup content. 640 if (window.matchMedia('(max-width: ' + Drupal.settings.eu_cookie_compliance.mobile_breakpoint + 'px)').matches && Drupal.settings.eu_cookie_compliance.use_mobile_message) { 641 $('.sliding-popup-bottom').not('.eu-cookie-withdraw-wrapper').html(Drupal.settings.eu_cookie_compliance.mobile_popup_html_info); 642 } 643 else { 644 $('.sliding-popup-bottom').not('.eu-cookie-withdraw-wrapper').html(Drupal.settings.eu_cookie_compliance.popup_html_info); 645 } 646 Drupal.eu_cookie_compliance.initPopup(); 647 Drupal.eu_cookie_compliance.resizeListener(); 648 } 649 else { 650 $('.sliding-popup-bottom').not('.eu-cookie-withdraw-wrapper').trigger('eu_cookie_compliance_popup_close').remove(); 651 $('body').removeClass('eu-cookie-compliance-popup-open'); 652 } 653 } 654 if (Drupal.settings.eu_cookie_compliance.withdraw_enabled) { 655 Drupal.eu_cookie_compliance.showWithdrawBanner(value); 656 } 657 }); 658 } 659 660 if (reloadPage) { 661 location.reload(); 662 } 663 664 Drupal.eu_cookie_compliance.setStatus(value); 665 }; 666 667 Drupal.eu_cookie_compliance.showWithdrawBanner = function (value) { 668 if (value === cookieValueAgreed && Drupal.settings.eu_cookie_compliance.withdraw_enabled) { 669 if (!Drupal.settings.eu_cookie_compliance.withdraw_button_on_info_popup) { 670 Drupal.eu_cookie_compliance.createWithdrawBanner(Drupal.settings.eu_cookie_compliance.withdraw_markup); 671 Drupal.eu_cookie_compliance.resizeListener(); 672 } 673 Drupal.eu_cookie_compliance.attachWithdrawEvents(); 674 Drupal.eu_cookie_compliance.positionTab(); 675 } 676 }; 677 678 Drupal.eu_cookie_compliance.setStatus = function (status) { 679 680 // Make a new observer & fire it to allow other scripts to hook in. 681 var preStatusSaveObject = new PreStatusSave(); 682 self.handleEvent('preStatusSave', preStatusSaveObject); 683 684 var date = new Date(); 685 var domain = Drupal.settings.eu_cookie_compliance.domain ? Drupal.settings.eu_cookie_compliance.domain : ''; 686 var path = Drupal.settings.eu_cookie_compliance.domain_all_sites ? '/' : Drupal.settings.basePath; 687 var cookieName = (typeof eu_cookie_compliance_cookie_name === 'undefined' || eu_cookie_compliance_cookie_name === '') ? 'cookie-agreed' : eu_cookie_compliance_cookie_name; 688 if (path.length > 1) { 689 var pathEnd = path.length - 1; 690 if (path.lastIndexOf('/') === pathEnd) { 691 path = path.substring(0, pathEnd); 692 } 693 } 694 695 var cookieSession = parseInt(Drupal.settings.eu_cookie_compliance.cookie_session); 696 if (cookieSession) { 697 $.cookie(cookieName, status, { path: path, domain: domain }); 698 } 699 else { 700 var lifetime = parseInt(Drupal.settings.eu_cookie_compliance.cookie_lifetime); 701 date.setDate(date.getDate() + lifetime); 702 $.cookie(cookieName, status, { expires: date, path: path, domain: domain }); 703 } 704 _euccCurrentStatus = status; 705 $(document).trigger('eu_cookie_compliance.changeStatus', [status]); 706 // Status set means something happened, update the version. 707 Drupal.eu_cookie_compliance.setVersion(); 708 709 // Store consent if applicable. 710 if (Drupal.settings.eu_cookie_compliance.store_consent && ((status === cookieValueAgreedS
710howThankYou && Drupal.settings.eu_cookie_compliance.popup_agreed_enabled) || (status === cookieValueAgreed && !Drupal.settings.eu_cookie_compliance.popup_agreed_enabled))) { 711 var url = Drupal.settings.basePath + Drupal.settings.pathPrefix + 'eu-cookie-compliance/store_consent/banner'; 712 $.post(url, {}, function (data) { }); 713 } 714 715 // Make a new observer & fire it to allow other scripts to hook in. 716 var postStatusSaveObject = new PostStatusSave(); 717 self.handleEvent('postStatusSave', postStatusSaveObject); 718 719 if (status === cookieValueDisagreed && Drupal.settings.eu_cookie_compliance.method === 'opt_out') { 720 euCookieComplianceBlockCookies = setInterval(Drupal.eu_cookie_compliance.BlockCookies, 5000); 721 } 722 }; 723 724 Drupal.eu_cookie_compliance.setAcceptedCategories = function (categories) { 725 726 // Make a new observer & fire it to allow other scripts to hook in. 727 var prePreferencesSaveObject = new PrePreferencesSave(); 728 self.handleEvent('prePreferencesSave', prePreferencesSaveObject); 729 730 var date = new Date(); 731 var domain = Drupal.settings.eu_cookie_compliance.domain ? Drupal.settings.eu_cookie_compliance.domain : ''; 732 var path = Drupal.settings.eu_cookie_compliance.domain_all_sites ? '/' : Drupal.settings.basePath; 733 var cookieName = (typeof eu_cookie_compliance_cookie_name === 'undefined' || eu_cookie_compliance_cookie_name === '') ? 'cookie-agreed-categories' : Drupal.settings.eu_cookie_compliance.cookie_name + '-categories'; 734 if (path.length > 1) { 735 var pathEnd = path.length - 1; 736 if (path.lastIndexOf('/') === pathEnd) { 737 path = path.substring(0, pathEnd); 738 } 739 } 740 var categoriesString = JSON.stringify(categories); 741 var cookie_session = parseInt(Drupal.settings.eu_cookie_compliance.cookie_session); 742 if (cookie_session) { 743 $.cookie(cookieName, categoriesString, { path: path, domain: domain }); 744 } 745 else { 746 var lifetime = parseInt(Drupal.settings.eu_cookie_compliance.cookie_lifetime); 747 date.setDate(date.getDate() + lifetime); 748 $.cookie(cookieName, categoriesString, { expires: date, path: path, domain: domain }); 749 } 750 _euccSelectedCategories = categories; 751 $(document).trigger('eu_cookie_compliance.changePreferences', [categories]); 752 753 // TODO: Store categories with consent if applicable? 754 // Make a new observer & fire it to allow other scripts to hook in. 755 var postPreferencesSaveObject = new PostPreferencesSave(); 756 self.handleEvent('postPreferencesSave', postPreferencesSaveObject); 757 }; 758 759 Drupal.eu_cookie_compliance.hasAgreed = function (category) { 760 var agreed = (_euccCurrentStatus === 1 || _euccCurrentStatus === 2); 761 762 if (category !== undefined && agreed) { 763 agreed = Drupal.eu_cookie_compliance.hasAgreedWithCategory(category); 764 } 765 766 return agreed; 767 }; 768 769 Drupal.eu_cookie_compliance.hasAgreedWithCategory = function (category) { 770 return $.inArray(category, _euccSelectedCategories) !== -1; 771 }; 772 773 Drupal.eu_cookie_compliance.showBanner = function () { 774 var showBanner = false; 775 if ((_euccCurrentStatus === 0 && Drupal.settings.eu_cookie_compliance.method === 'default') || _euccCurrentStatus === null) { 776 if (!Drupal.settings.eu_cookie_compliance.disagree_do_not_show_popup || _euccCurrentStatus === null) { 777 showBanner = true; 778 } 779 } 780 else if (_euccCurrentStatus === 1 && Drupal.settings.eu_cookie_compliance.popup_agreed_enabled) { 781 showBanner = true; 782 } 783 else if (_euccCurrentStatus === 2 && Drupal.settings.eu_cookie_compliance.withdraw_enabled) { 784 showBanner = true; 785 } 786 787 return showBanner; 788 }; 789 790 Drupal.eu_cookie_compliance.cookiesEnabled = function () { 791 var cookieEnabled = navigator.cookieEnabled; 792 if (typeof navigator.cookieEnabled === 'undefined' && !cookieEnabled) { 793 document.cookie = 'testCookie'; 794 cookieEnabled = (document.cookie.indexOf('testCookie') !== -1); 795 } 796 797 return cookieEnabled; 798 }; 799 800 Drupal.eu_cookie_compliance.cookieMatches = function (cookieName, pattern) { 801 if (cookieName === pattern) { 802 return true; 803 } 804 if (pattern.indexOf('*') < 0) { 805 return false; 806 } 807 try { 808 var regexp = new RegExp('^' + pattern.replace(/\./g, '\\.').replace(/\*/g, '.+') + '$', 'g'); 809 return regexp.test(cookieName); 810 } 811 catch (err) { 812 return false; 813 } 814 }; 815 816 Drupal.eu_cookie_compliance.isAllowed = function (cookieName) { 817 // Skip the PHP session cookie. 818 if (cookieName.indexOf('SESS') === 0 || cookieName.indexOf('SSESS') === 0) { 819 return true; 820 } 821 // Split the allowed cookies. 822 var euCookieComplianceAllowlist = Drupal.settings.eu_cookie_compliance.allowed_cookies.split(/\r\n|\n|\r/g); 823 824 // Add the EU Cookie Compliance cookie. 825 euCookieComplianceAllowlist.push((typeof Drupal.settings.eu_cookie_compliance.cookie_name === 'undefined' || Drupal.settings.eu_cookie_compliance.cookie_name === '') ? 'cookie-agreed' : Drupal.settings.eu_cookie_compliance.cookie_name); 826 euCookieComplianceAllowlist.push((typeof Drupal.settings.eu_cookie_compliance.cookie_name === 'undefined' || Drupal.settings.eu_cookie_compliance.cookie_name === '') ? 'cookie-agreed-categories' : Drupal.settings.eu_cookie_compliance.cookie_name + '-categories'); 827 euCookieComplianceAllowlist.push((typeof Drupal.settings.eu_cookie_compliance.cookie_name === 'undefined' || Drupal.settings.eu_cookie_compliance.cookie_name === '') ? 'cookie-agreed-version' : Drupal.settings.eu_cookie_compliance.cookie_name + '-version'); 828 829 // Check if the cookie is allowed. 830 for (var item in euCookieComplianceAllowlist) { 831 // Defensively check types for comparison. 832 if (typeof euCookieComplianceAllowlist[item] === "string") { 833 if (Drupal.eu_cookie_compliance.cookieMatches(cookieName, euCookieComplianceAllowlist[item])) { 834 return true; 835 } 836 // Handle cookie names that are prefixed with a category. 837 if (Drupal.settings.eu_cookie_compliance.method === 'categories') { 838 var separatorPos = euCookieComplianceAllowlist[item].indexOf(":"); 839 if (separatorPos !== -1) { 840 var category = euCookieComplianceAllowlist[item].substr(0, separatorPos); 841 var wlCookieName = euCookieComplianceAllowlist[item].substr(separatorPos + 1); 842 843 if (Drupal.eu_cookie_compliance.cookieMatches(cookieName, wlCookieName) && Drupal.eu_cookie_compliance.hasAgreedWithCategory(category)) { 844 return true; 845 } 846 } 847 } 848 } 849 } 850 851 return false; 852 } 853 854 // This code upgrades the cookie agreed status when upgrading for an old version. 855 Drupal.eu_cookie_compliance.updateCheck = function () { 856 var legacyCookie = 'cookie-agreed-' + Drupal.settings.eu_cookie_compliance.popup_language; 857 var domain = Drupal.settings.eu_cookie_compliance.domain ? Drupal.settings.eu_cookie_compliance.domain : ''; 858 var path = Drupal.settings.eu_cookie_compliance.domain_all_sites ? '/' : Drupal.settings.basePath; 859 var cookie = $.cookie(legacyCookie); 860 var date = new Date(); 861 var cookieName = (typeof eu_cookie_compliance_cookie_name === 'undefined' || eu_cookie_compliance_cookie_name === '') ? 'cookie-agreed' : eu_cookie_compliance_cookie_name; 862 863 // jQuery.cookie 1.0 (bundled with Drupal) returns null, 864 // jQuery.cookie 1.4.1 (bundled with some themes) returns undefined. 865 // We had a 1.4.1 related bug where the value was set to 'null' (string). 866 if (cookie !== undefined && cookie !== null && cookie !== 'null') { 867 date.setDate(date.getDate() + parseInt(Drupal.settings.eu_cookie_compliance.cookie_lifetime)); 868 $.cookie(cookieName, cookie, { expires: date, path: path, domain: domain }); 869 870 // Use removeCookie if the function exists. 871 if (typeof $.removeCookie !== 'undefined') { 872 $.removeCookie(legacyCookie); 873 } 874 else { 875 $.cookie(legacyCookie, null, { path: path, domain: domain }); 876 } 877 } 878 }; 879 880 Drupal.eu_cookie_compliance.getVersion = function () { 881 var cookieName = (typeof Drupal.settings.eu_cookie_compliance.cookie_name === 'undefined' || Drupal.settings.eu_cookie_compliance.cookie_name === '') ? 'cookie-agreed-version' : Drupal.settings.eu_cookie_compliance.cookie_name + '-version'; 882 return $.cookie(cookieName); 883 }; 884 885 Drupal.eu_cookie_compliance.setVersion = function () { 886 var date = new Date(); 887 var domain = Drupal.settings.eu_cookie_compliance.domain ? Drupal.settings.eu_cookie_compliance.domain : ''; 888 var path = Drupal.settings.eu_cookie_compliance.domain_all_sites ? '/' : Drupal.settings.basePath; 889 var cookieName = (typeof Drupal.settings.eu_cookie_compliance.cookie_name === 'undefined' || Drupal.settings.eu_cookie_compliance.cookie_name === '') ? 'cookie-agreed-version' : Drupal.settings.eu_cookie_compliance.cookie_name + '-version'; 890 891 if (path.length > 1) { 892 var pathEnd = path.length - 1; 893 if (path.lastIndexOf('/') === pathEnd) { 894 path = path.substring(0, pathEnd); 895 } 896 } 897 var eucc_version = Drupal.settings.eu_cookie_compliance.cookie_policy_version; 898 var cookie_session = parseInt(Drupal.settings.eu_cookie_compliance.cookie_session); 899 if (cookie_session) { 900 $.cookie(cookieName, eucc_version, { path: path, domain: domain }); 901 } 902 else { 903 var lifetime = parseInt(Drupal.settings.eu_cookie_compliance.cookie_lifetime); 904 date.setDate(date.getDate() + lifetime); 905 $.cookie(cookieName, eucc_version, { expires: date, path: path, domain: domain }); 906 } 907 }; 908 909 // Load blocked scripts if the user has agreed to being tracked. 910 var euCookieComplianceHasLoadedScripts = false; 911 var euCookieComplianceHasLoadedScriptsForCategory = []; 912 $(function () { 913 if (Drupal.eu_cookie_compliance.hasAgreed() 914 || (_euccCurrentStatus === null && Drupal.settings.eu_cookie_compliance.method !== 'opt_in' && Drupal.settings.eu_cookie_compliance.method !== 'categories') 915 ) { 916 if (typeof euCookieComplianceLoadScripts === "function") { 917 euCookieComplianceLoadScripts(); 918 } 919 euCookieComplianceHasLoadedScripts = true; 920 921 if (Drupal.settings.eu_cookie_compliance.method === 'categories') { 922 Drupal.eu_cookie_compliance.loadCategoryScripts(_euccSelectedCategories); 923 } 924 } 925 }); 926 927 // Block cookies when the user hasn't agreed. 928 Drupal.behaviors.eu_cookie_compliance_popup_block_cookies = { 929 initialized: false, 930 attach: function (context, settings) { 931 if (!Drupal.behaviors.eu_cookie_compliance_popup_block_cookies.initialized && settings.eu_cookie_compliance) { 932 Drupal.behaviors.eu_cookie_compliance_popup_block_cookies.initialized = true; 933 if (settings.eu_cookie_compliance.automatic_cookies_removal && 934 ((settings.eu_cookie_compliance.method === 'opt_in' && (_euccCurrentStatus === null || !Drupal.eu_cookie_compliance.hasAgreed()))
935 || (settings.eu_cookie_compliance.method === 'opt_out' && !Drupal.eu_cookie_compliance.hasAgreed() && _euccCurrentStatus !== null) 936 || (Drupal.settings.eu_cookie_compliance.method === 'categories')) 937 ) { 938 // Split the allowed cookies. 939 var euCookieComplianceAllowlist = settings.eu_cookie_compliance.allowed_cookies.split(/\r\n|\n|\r/g); 940 941 // Add the EU Cookie Compliance cookie. 942 var cookieName = (typeof eu_cookie_compliance_cookie_name === 'undefined' || eu_cookie_compliance_cookie_name === '') ? 'cookie-agreed' : eu_cookie_compliance_cookie_name; 943 euCookieComplianceAllowlist.push(cookieName); 944 945 euCookieComplianceBlockCookies = setInterval(Drupal.eu_cookie_compliance.BlockCookies, 5000); 946 } 947 } 948 } 949 } 950 951 Drupal.eu_cookie_compliance.BlockCookies = function () { 952 // Load all cookies from jQuery. 953 var cookies = $.cookie(); 954 955 // Check each cookie and try to remove it if it's not allowed. 956 for (var i in cookies) { 957 var remove = true; 958 var hostname = window.location.hostname; 959 var cookieRemoved = false; 960 var index = 0; 961 962 remove = !Drupal.eu_cookie_compliance.isAllowed(i); 963 964 // Remove the cookie if it's not allowed. 965 if (remove) { 966 while (!cookieRemoved && hostname !== '') { 967 // Attempt to remove. 968 cookieRemoved = $.removeCookie(i, { domain: '.' + hostname, path: '/' }); 969 if (!cookieRemoved) { 970 cookieRemoved = $.removeCookie(i, { domain: hostname, path: '/' }); 971 } 972 973 index = hostname.indexOf('.'); 974 975 // We can be on a sub-domain, so keep checking the main domain as well. 976 hostname = (index === -1) ? '' : hostname.substring(index + 1); 977 } 978 979 // Some jQuery Cookie versions don't remove cookies well. Try again
980 // using plain js. 981 if (!cookieRemoved) { 982 document.cookie = i + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/;'; 983 } 984 } 985 } 986 } 987 988 /** 989 * Filter the event listeners by event name and return the list of handlers. 990 * 991 * @param forEventName 992 * 993 * @returns {[]} 994 */ 995 var filterQueue = function (forEventName) { 996 var handlers = []; 997 if (typeof Drupal.eu_cookie_compliance !== 'undefined' && 998 typeof Drupal.eu_cookie_compliance.queue !== 'undefined' && 999 Drupal.eu_cookie_compliance.queue.length) { 1000 // Loop over the list of arguments (objects) pushed into the queue. 1001 for (var i = 0; i < Drupal.eu_cookie_compliance.queue.length; i++) { 1002 if (Drupal.eu_cookie_compliance.queue[i].length) { 1003 var queueItem = Drupal.eu_cookie_compliance.queue[i]; 1004 var eventName = queueItem[0]; 1005 var eventHandler = queueItem[1]; 1006 // If the first element is a string and the second is a function. 1007 if (typeof eventName === 'string' && typeof eventHandler === 'function') { 1008 // And the string matches the event name. 1009 if (eventName === forEventName) { 1010 // Return the functions so they can be executed. 1011 handlers.push(eventHandler); 1012 } 1013 } 1014 } 1015 } 1016 } 1017 return handlers; 1018 } 1019 1020 /** 1021 * Handle event by finding and executing handlers pushed to the queue. 1022 */ 1023 self.handleEvent = function (eventName, observer) { 1024 var handlers = filterQueue(eventName); 1025 for (var i = 0; i < handlers.length; i++) { 1026 if (typeof handlers[i] !== 'undefined') { 1027 observer.subscribe(handlers[i]); 1028 observer.fire({ 1029 currentStatus: _euccCurrentStatus, 1030 currentCategories: _euccSelectedCategories 1031 }); 1032 observer.unsubscribe(handlers[i]); 1033 } 1034 } 1035 }; 1036 1037 /** 1038 * Observer: triggered before status gets read from cookie. 1039 */ 1040 var PreStatusLoad = (function () { 1041 // Constructor. 1042 var PreStatusLoad = function () { 1043 // Observers. 1044 this.handlers = []; 1045 }; 1046 // Convenience var for the prototype. 1047 var prototype = PreStatusLoad.prototype; 1048 prototype.subscribe = function (fn) { 1049 this.handlers.push(fn); 1050 }; 1051 prototype.unsubscribe = function (fn) { 1052 this.handlers = this.handlers.filter( 1053 function (item) { 1054 if (item !== fn) { 1055 return item; 1056 } 1057 } 1058 ); 1059 }; 1060 prototype.fire = function (o, thisObj) { 1061 var scope = thisObj || window; 1062 this.handlers.forEach(function (item) { 1063 item.call(scope, o); 1064 }); 1065 }; 1066 return PreStatusLoad; 1067 })(); 1068 1069 /** 1070 * Observer: triggered after status was read from cookie and stored in private variable. 1071 */ 1072 var PostStatusLoad = (function () { 1073 // Constructor. 1074 var PostStatusLoad = function () { 1075 // Observers. 1076 this.handlers = []; 1077 }; 1078 // Convenience var for the prototype. 1079 var prototype = PostStatusLoad.prototype; 1080 prototype.subscribe = function (fn) { 1081 this.handlers.push(fn); 1082 }; 1083 prototype.unsubscribe = function (fn) { 1084 this.handlers = this.handlers.filter( 1085 function (item) { 1086 if (item !== fn) { 1087 return item; 1088 } 1089 } 1090 ); 1091 }; 1092 prototype.fire = function (o, thisObj) { 1093 var scope = thisObj || window; 1094 this.handlers.forEach(function (item) { 1095 item.call(scope, o); 1096 }); 1097 }; 1098 return PostStatusLoad; 1099 })(); 1100 1101 /** 1102 * Observer: triggered before status gets saved into cookie. 1103 */ 1104 var PreStatusSave = (function () { 1105 // Constructor. 1106 var PreStatusSave = function () { 1107 // Observers. 1108 this.handlers = []; 1109 }; 1110 // Convenience var for the prototype. 1111 var prototype = PreStatusSave.prototype; 1112 prototype.subscribe = function (fn) { 1113 this.handlers.push(fn); 1114 }; 1115 prototype.unsubscribe = function (fn) { 1116 this.handlers = this.handlers.filter( 1117 function (item) { 1118 if (item !== fn) { 1119 return item; 1120 } 1121 } 1122 ); 1123 }; 1124 prototype.fire = function (o, thisObj) { 1125 var scope = thisObj || window;
1126 this.handlers.forEach(function (item) { 1127 item.call(scope, o); 1128 }); 1129 }; 1130 return PreStatusSave; 1131 })(); 1132 1133 /** 1134 * Observer: triggered after status was saved into cookie. 1135 */ 1136 var PostStatusSave = (function () { 1137 // Constructor. 1138 var PostStatusSave = function () { 1139 // Observers. 1140 this.handlers = []; 1141 }; 1142 // Convenience var for the prototype. 1143 var prototype = PostStatusSave.prototype; 1144 prototype.subscribe = function (fn) { 1145 this.handlers.push(fn); 1146 }; 1147 prototype.unsubscribe = function (fn) { 1148 this.handlers = this.handlers.filter( 1149 function (item) { 1150 if (item !== fn) { 1151 return item; 1152 } 1153 } 1154 ); 1155 }; 1156 prototype.fire = function (o, thisObj) { 1157 var scope = thisObj || window; 1158 this.handlers.forEach(function (item) { 1159 item.call(scope, o); 1160 }); 1161 }; 1162 return PostStatusSave; 1163 })(); 1164 1165 /** 1166 * Observer: triggered before categories are read from cookie. 1167 */ 1168 var PrePreferencesLoad = (function () { 1169 // Constructor. 1170 var prePreferencesLoad = function () { 1171 // Observers. 1172 this.handlers = []; 1173 }; 1174 // Convenience var for the prototype. 1175 var prototype = prePreferencesLoad.prototype; 1176 prototype.subscribe = function (fn) { 1177 this.handlers.push(fn); 1178 }; 1179 prototype.unsubscribe = function (fn) { 1180 this.handlers = this.handlers.filter( 1181 function (item) { 1182 if (item !== fn) { 1183 return item; 1184 } 1185 } 1186 ); 1187 }; 1188 prototype.fire = function (o, thisObj) { 1189 var scope = thisObj || window; 1190 this.handlers.forEach(function (item) { 1191 item.call(scope, o); 1192 }); 1193 }; 1194 return prePreferencesLoad; 1195 })(); 1196 1197 /** 1198 * Observer: triggered after categories were read from cookie. 1199 */ 1200 var PostPreferencesLoad = (function () { 1201 // Constructor. 1202 var postPreferencesLoad = function () { 1203 // Observers. 1204 this.handlers = []; 1205 }; 1206 // Convenience var for the prototype. 1207 var prototype = postPreferencesLoad.prototype; 1208 prototype.subscribe = function (fn) { 1209 this.handlers.push(fn); 1210 }; 1211 prototype.unsubscribe = function (fn) { 1212 this.handlers = this.handlers.filter( 1213 function (item) { 1214 if (item !== fn) { 1215 return item; 1216 } 1217 } 1218 ); 1219 }; 1220 prototype.fire = function (o, thisObj) { 1221 var scope = thisObj || window; 1222 this.handlers.forEach(function (item) { 1223 item.call(scope, o); 1224 }); 1225 }; 1226 return postPreferencesLoad; 1227 })(); 1228 1229 /** 1230 * Observer: triggered before categories are being saved to cookie. 1231 */ 1232 var PrePreferencesSave = (function () { 1233 // Constructor. 1234 var prePreferencesSave = function () { 1235 // Observers. 1236 this.handlers = []; 1237 }; 1238 // Convenience var for the prototype. 1239 var prototype = prePreferencesSave.prototype; 1240 prototype.subscribe = function (fn) { 1241 this.handlers.push(fn); 1242 }; 1243 prototype.unsubscribe = function (fn) { 1244 this.handlers = this.handlers.filter( 1245 function (item) { 1246 if (item !== fn) { 1247 return item; 1248 } 1249 } 1250 ); 1251 }; 1252 prototype.fire = function (o, thisObj) { 1253 var scope = thisObj || window; 1254 this.handlers.forEach(function (item) { 1255 item.call(scope, o); 1256 }); 1257 }; 1258 return prePreferencesSave; 1259 })(); 1260 1261 /** 1262 * Observer: triggered after categories were saved to cookie. 1263 */ 1264 var PostPreferencesSave = (function () { 1265 // Constructor. 1266 var postPreferencesSave = function () { 1267 // Observers. 1268 this.handlers = []; 1269 }; 1270 // Convenience var for the prototype. 1271 var prototype = postPreferencesSave.prototype; 1272 prototype.subscribe = function (fn) { 1273 this.handlers.push(fn); 1274 }; 1275 prototype.unsubscribe = function (fn) { 1276 this.handlers = this.handlers.filter( 1277 function (item) { 1278 if (item !== fn) { 1279 return item; 1280 } 1281 } 1282 ); 1283 }; 1284 prototype.fire = function (o, thisObj) { 1285 var scope = thisObj || window;
1286 this.handlers.forEach(function (item) { 1287 item.call(scope, o); 1288 }); 1289 }; 1290 return postPreferencesSave; 1291 })(); 1292 1293})(jQuery); 1294; 1295(function ($) { 1296 'use strict'; 1297 1298 Drupal.behaviors.euccx = { 1299 attach: function (context, settings) { 1300 1301 $(window).load(function () { 1302 Drupal.euccx.init(); 1303 }); 1304 1305 } 1306 }; 1307 1308 Drupal.euccx = {}; 1309 1310 // Entry function for our script. 1311 // Delegates the jobs to other functions. 1312 Drupal.euccx.init = function () { 1313 // Check if our environment is valid and return if it's not 1314 if (!Drupal.euccx.verifyEnvironment()) { 1315 return; 1316 } 1317 Drupal.euccx.handleBanner(); 1318 Drupal.euccx.handleCookieSettingsPage(); 1319 Drupal.euccx.processStatus(Drupal.euccx.getCookieStatus()); 1320 }; 1321 1322 // Since we are using the state of EU Cookie Compliance in multiple steps of 1323 // the process, we need to make sure that its main function is available. 1324 // This is important to avoid javascript errors in administrative pages where 1325 // the euccx block is loaded but the EUCC is "out of context". 1326 Drupal.euccx.verifyEnvironment = function () { 1327 return (typeof Drupal.eu_cookie_compliance !== 'undefined' && 1328 Drupal.eu_cookie_compliance !== null); 1329 }; 1330 1331 /** 1332 * Helper function which returns true, if eucc uses opt-in by categories 1333 * method. This has several larger implications for us. 1334 * 1335 * See https://www.drupal.org/project/euccx/issues/3144073 for details. 1336 * 1337 * @return boolean 1338 */ 1339 Drupal.euccx.usesCategories = function() { 1340 return Drupal.settings.eu_cookie_compliance.method === 'categories'; 1341 } 1342 1343 // Handle clicks on the main banner 1344 Drupal.euccx.handleBanner = function () { 1345 $(document).ready(function () { 1346 // When the user clicks on the agree button of the EU Cookie Compliance 1347 // module we consider it a "carte blanche" consent for all cookies that 1348 // are defined by our plugins. Instead of waiting for the next page 1349 // refresh, we can attach an event that unblocks everything right here, 1350 // right now. 1351 $('.agree-button').click(function () { 1352 Drupal.euccx.unblockAll(); 1353 Drupal.euccx.yettUnblockAll(); 1354 }); 1355 1356 // If the administrator did not enable the option in the admin interface 1357 // we do not need to assign any kind of actions to elements that have the 1358 // class "euccx-disable-all". 1359 if (!Drupal.settings.euccx.dab) { 1360 return; 1361 } 1362 // When the user clicks on the disagree button, all we need to do is set 1363 // our cookie to a blank value (by convention). This will tell prevent our 1364 // javascript from enabling anything that was blocked in the beginning. 1365 $('body').on('click', '.euccx-disable-all', function (e) { 1366 e.preventDefault(); 1367 Drupal.euccx.setCookie('0'); 1368 // We also need to call the decline action of the EU Cookie Compliance 1369 // module which will handle the status of EUCC and also close the banner 1370 // or do some other stuff depending on its settings. 1371 Drupal.eu_cookie_compliance.declineAction(); 1372 }); 1373 }); 1374 }; 1375 1376 // If we are in the page where the cookie settings' block is included, we need 1377 // to do some stuff. 1378 Drupal.euccx.handleCookieSettingsPage = function () { 1379 var cookieBlock = $('#cookie-tabs'); 1380 // If the cookie management block is not in the page, exit. 1381 // No need to run extra code for something that is not even in the page 1382 if (!cookieBlock.length) { 1383 return; 1384 } 1385 1386 // Create the jquery ui tabs for the cookie management block 1387 cookieBlock.tabs(); 1388 1389 // Behaviour is different when using opt-in categories. 1390 if (!Drupal.euccx.usesCategories()) { 1391 // When opt-in categories are NOT used, we are offering switches 1392 // for each script. 1393 $('#sliding-popup').hide(); 1394 // ... handle the switches 1395 Drupal.euccx.handleSwitches(); 1396 // ... and attach functionality for the save key 1397 Drupal.euccx.handleCookieSettingsBehaviors();
1398 } else { 1399 // Special handling for category switches: 1400 Drupal.euccx.handleCategorySwitches(); 1401 } 1402 }; 1403 1404 // The function that decides what to do with the current user's status. 1405 // Responsible for unblocking javascript when needed. 1406 Drupal.euccx.processStatus = function (status) { 1407 1408 // If the main eucc cookie is not set, it means that the user has not agreed 1409 // to anything yet. Move on. 1410 // We also check if the status of cookie-eucc is equal to the string "0" 1411 // which means that the user denied the cookies. 1412 if (!status['cookie-eucc'] || status['cookie-eucc'] === '0') { 1413 // If the main cookie has not been set yet, we have no reason to override 1414 // the blocks yet. This way, if for example the user accepts all our 1415 // cookies we will not miss on a google adsense load. 1416 return; 1417 } 1418 1419 // If the euccx cookie was never set but the eucc cookie was set (checked 1420 // for that above) it means that the user agreed to everything so we need to 1421 // unblock everything and move on. 1422 if (!status['cookie-euccx'] && !Drupal.euccx.usesCategories()) { 1423 Drupal.euccx.unblockAll(); 1424 Drupal.euccx.yettUnblockAll(); 1425 return; 1426 } 1427 1428 // We are now in the case where both cookies are set. We need to surgically 1429 // unblock code depending on its plugin's settings. 1430 // We use getAcceptedCategoriesPluginNames() to respect opt-in categories 1431 // if used. 1432 var pluginNames = Drupal.euccx.getAcceptedCategoriesPluginNames(); 1433 var settings = Drupal.settings.euccx; 1434 for (var i = 0; i < pluginNames.length; i++) { 1435 var currentPlugin = pluginNames[i]; 1436 // If current plugin is not in the list of the plugins that the user chose 1437 // to keep enabled, we move on to the next plugin. 1438 if (status['cookie-euccx'] && status['cookie-euccx'].indexOf(currentPlugin) === -1) { 1439 Drupal.euccx.handleBlockOverrides(currentPlugin); 1440 continue; 1441 } 1442 1443 1444 // If the specific plugin has a YETT blacklist defined, we need to get it 1445 // and whitelist the set of rules 1446 var blacklist = false; 1447 if (settings['plugins'] && settings['plugins'][currentPlugin] && 1448 settings['plugins'][currentPlugin]['blacklist']) { 1449 blacklist = settings['plugins'][currentPlugin]['blacklist']; 1450 } 1451 1452 if (blacklist) { 1453 Drupal.euccx.yettUnblockPlugin(blacklist); 1454 } 1455 1456 // If the specific plugin has a js_exclude list, there will be a function 1457 // defined that we need to call in order to run the scripts. 1458 var js_exclude = false; 1459 if (settings['plugins'] && settings['plugins'][currentPlugin] && 1460 settings['plugins'][currentPlugin]['js_exclude']) { 1461 js_exclude = settings['plugins'][currentPlugin]['js_exclude']; 1462 } 1463 1464 // Unblock if js_exclude OR no specific cookie has been set 1465 // (which can only happen if using opt-in categories) 1466 if (js_exclude || !status['cookie-euccx']) { 1467 Drupal.euccx.unblockPlugin(currentPlugin); 1468 } 1469 1470 } 1471 }; 1472 1473 // Check whether our plugin has defined any block overrides. If it did, watch 1474 // the DOM for the selector and act accordingly. 1475 Drupal.euccx.handleBlockOverrides = function (plugin) { 1476 $(document).ready(function () { 1477 var settings = Drupal.settings.euccx; 1478 if (settings && settings['plugins']) { 1479 var plugins = []; 1480 if (plugin === '') { 1481 for (var pluginName in settings['plugins']) { 1482 if (!{}.hasOwnProperty.call(settings.plugins, pluginName)) { 1483 continue; 1484 } 1485 plugins.push(pluginName); 1486 } 1487 } 1488 else { 1489 if ({}.hasOwnProperty.call(settings.plugins, plugin)) { 1490 plugins.push(plugin); 1491 } 1492 } 1493 for (var i = 0; i < plugins.length; i++) { 1494 if (!{}.hasOwnProperty.call( 1495 settings['plugins'][plugins[i]], 1496 'overrides')) { 1497 continue; 1498 } 1499 for (var key in settings['plugins'][plugins[i]]['overrides']) { 1500 if (!{}.hasOwnProperty.call( 1501 settings['plugins'][plugins[i]]['overrides'], key)) { 1502 continue; 1503 } 1504 $(key) 1505 .empty() 1506 .append(settings['plugins'][plugins[i]]['overrides'][key]); 1507 } 1508 } 1509 } 1510 });
1511 }; 1512 1513 // Make sure that when the user hits the save button, it actually does 1514 // something. 1515 Drupal.euccx.handleCookieSettingsBehaviors = function () { 1516 $('body').on('click', '.cookie-settings-save', function (e) { 1517 try { 1518 e.preventDefault(); 1519 // Make sure that the EU Cookie Compliance Module has set its cookie 1520 Drupal.eu_cookie_compliance.acceptAction(); 1521 var plugin; 1522 // Create our cookie content 1523 // We need to at least have some content in the cookie in order to make 1524 // sure that we can check its contents easier later (if for example the 1525 // cookie was empty, it would not have been possible to check the user's 1526 // settings with a simple !status['cookie-euccx']. 1527 var cookieData = 'cookies-enabled:'; 1528 $('#cookie-tabs input').each(function () { 1529 if ($(this).prop('checked')) { 1530 plugin = $(this).attr('name').match(/-[^-]+$/)[0].substring(1); 1531 cookieData += plugin + '|'; 1532 } 1533 }); 1534 // ... set our cookie 1535 Drupal.euccx.setCookie(cookieData); 1536 // ... and reload the page so that the user gets some feedback of 1537 // something happening and if for example he enabled google analytics it 1538 // records the visit. 1539 location.reload(); 1540 } 1541 catch (error) { 1542 // console.log(error) 1543 } 1544 }); 1545 }; 1546 1547 // Check the cookies that are stored in the user's browser and a return an 1548 // object with all the relevant information. 1549 Drupal.euccx.getCookieStatus = function () { 1550 var status = {}; 1551 var cookieName = (typeof eu_cookie_compliance_cookie_name === 'undefined' || 1552 eu_cookie_compliance_cookie_name === '') ? 1553 'cookie-agreed' : 1554 eu_cookie_compliance_cookie_name; 1555 var cookieEUCC = Drupal.euccx.getCookie(cookieName); 1556 var cookieEUCCX = Drupal.euccx.getCookie('cookie-extras-agreed'); 1557 1558 status['cookie-eucc'] = cookieEUCC; 1559 status['cookie-euccx'] = cookieEUCCX; 1560 if (typeof cookieEUCCX === 'string') { 1561 var pluginNames = Drupal.euccx.getPluginNames(); 1562 for (var i = 0; i < pluginNames.length; i++) { 1563 status[pluginNames[i]] = (cookieEUCCX.indexOf(pluginNames[i]) !== -1); 1564 } 1565 } 1566 return status; 1567 }; 1568 1569 // Unblocks all plugins that used yett 1570 Drupal.euccx.yettUnblockAll = function () { 1571 if (!window.yett) { 1572 return; 1573 } 1574 window.yett.unblock(); 1575 }; 1576 1577 // Whitelist a specific set of scripts that were blocked via yett 1578 Drupal.euccx.yettUnblockPlugin = function (rules) { 1579 if (!window.yett) { 1580 return; 1581 } 1582 // This should work now after a modification was made to the yett library. 1583 // See: https://github.com/snipsco/yett/issues/11 for more info on what the 1584 // problem was and how it was solved in 0.1.8 version of yett. 1585 1586 // Convert rules to RegExps 1587 var regexp_rules = rules.map(function(rule) { 1588 // Strip leading/trailing slash. 1589 rule = rule.replace(/^\/(.+)\/$/, "$1"); 1590 return new RegExp(rule); 1591 }); 1592 1593 window.yett.unblock.apply(this, regexp_rules); 1594 }; 1595 1596 // Unblock all plugins 1597 Drupal.euccx.unblockAll = function () { 1598 var plugins = Drupal.euccx.getPluginNames(); 1599 for (var i = 0; i < plugins.length; i++) { 1600 Drupal.euccx.unblockPlugin(plugins[i]); 1601 } 1602 }; 1603 1604 /** 1605 * Returns a unique list of all accepted categories plugin names. 1606 * If categories are not used as opt-in method, returns all plugins. 1607 * 1608 * @return [] 1609 */ 1610 Drupal.euccx.getAcceptedCategoriesPluginNames = function () { 1611 var plugins = []; 1612 var categoryPlugins; 1613 if (Drupal.euccx.usesCategories()) { 1614 // Opt-in by categories is used, we may only unblock all from allowed 1615 // categories: 1616 if(!Drupal.eu_cookie_compliance.hasAgreed()){ 1617 // We can return early here, nothing accepted at all! 1618 return []; 1619 } 1620 var acceptedCategories = Drupal.eu_cookie_compliance.getAcceptedCategories(); 1621 for (var a = 0; a < acceptedCategories.length; a++) { 1622 categoryPlugins = Drupal.euccx.getPluginNamesByOptInCategory(acceptedCategories[a]); 1623 if(categoryPlugins && categoryPlugins.length > 0){ 1624 plugins = plugins.concat(categoryPlugins.filter(function(el) { 1625 return plugins.indexOf(el) === -1; 1626 })); 1627 } 1628 } 1629 } else { 1630 // Not using categories, all defined plugins are accepted: 1631 plugins = Drupal.euccx.getPluginNames(); 1632 } 1633 return plugins; 1634 }; 1635 1636 /** 1637 * Return an array of the plugin names that are in a given category. 1638 * 1639 * @param optInCategory The machine name of the eucc opt-in category 1640 * @return [] 1641 */ 1642 Drupal.euccx.getPluginNamesByOptInCategory = function (optInCategory) { 1643 if (Drupal.settings.euccx && Drupal.settings.euccx.plugins) { 1644 var pluginNames = []; 1645 for (var key in Drupal.settings.euccx.plugins) { 1646 if ({}.hasOwnProperty.call(Drupal.settings.euccx.plugins, key)) { 1647 if (Drupal.settings.euccx.plugins[key].opt_in_category == optInCategory) { 1648 pluginNames.push(key); 1649 } 1650 } 1651 } 1652 return pluginNames; 1653 } 1654 return false; 1655 }; 1656 1657 // Given a plugin name execute the function that will unblock its code 1658 Drupal.euccx.unblockPlugin = function (pluginName) { 1659 var functionName = 'euccx' + pluginName + 'Load'; 1660 try { 1661 window[functionName](); 1662 } 1663 catch (e) { 1664 // console.log(e); 1665 } 1666 }; 1667 1668 // Return an array of the plugin names that are defined 1669 Drupal.euccx.getPluginNames = function () { 1670 if (Drupal.settings.euccx && Drupal.settings.euccx.plugins) { 1671 var pluginNames = []; 1672 for (var key in Drupal.settings.euccx.plugins) { 1673 if ({}.hasOwnProperty.call(Drupal.settings.euccx.plugins, key)) { 1674 pluginNames.push(key); 1675 } 1676 } 1677 return pluginNames; 1678 } 1679 return false; 1680 }; 1681 1682 // Return false when the cookie is not properly set or the cookie value when 1683 // it is (properly set). 1684 Drupal.euccx.getCookie = function (cookieName) { 1685 var cookieValue = $.cookie(cookieName); 1686 if (typeof (cookieValue) === 'undefined' || (cookieValue === null)) { 1687 return false; 1688 } 1689 return cookieValue; 1690 }; 1691 1692 // This is using the exact same code with EU Cookie since our cookie is also 1693 // respecting most of the settings that the user supplied in EU Cookie 1694 // Compliance module. 1695 Drupal.euccx.setCookie = function (content) { 1696 try { 1697 var date = new Date(); 1698 var domain = Drupal.settings.eu_cookie_compliance.domain ? 1699 Drupal.settings.eu_cookie_compliance.domain : 1700 ''; 1701 var path = Drupal.settings.basePath; 1702 var cookieName = 'cookie-extras-agreed'; 1703 if (path.length > 1) { 1704 var pathEnd = path.length - 1; 1705 if (path.lastIndexOf('/') === pathEnd) { 1706 path = path.substring(0, pathEnd); 1707 } 1708 } 1709 var cookieSession = parseInt( 1710 Drupal.settings.eu_cookie_compliance.cookie_session 1711 ); 1712 1713 if (cookieSession) { 1714 $.cookie(cookieName, content, {path: path, domain: domain}); 1715 } 1716 else { 1717 var lifetime = parseInt( 1718 Drupal.settings.eu_cookie_compliance.cookie_lifetime 1719 ); 1720 date.setDate(date.getDate() + lifetime); 1721 $.cookie(cookieName, content, { 1722 expires: date, 1723 path: path, 1724 domain: domain 1725 }); 1726 } 1727 1728 // Store consent if applicable. 1729 if (Drupal.settings.eu_cookie_compliance.store_consent) { 1730 var url = Drupal.settings.basePath; 1731 url += Drupal.settings.pathPrefix; 1732 url += 'eu-cookie-compliance/store_consent/banner'; 1733 1734 $.post(url, {}, function (data) { });
1735 } 1736 } 1737 catch (e) { 1738 // console.log(e); 1739 } 1740 }; 1741 1742 // The switches in the block are always set to off. It's up to us to turn them 1743 // on, if the cookie stored tells us so. 1744 Drupal.euccx.handleSwitches = function () { 1745 // If the cookie is not set, just turn them on by default 1746 var cookieValue = Drupal.euccx.getCookie('cookie-extras-agreed'); 1747 // If the cookie has never been set, we need to see if the user selected to 1748 // have the switches turned on or off by default 1749 // see: https://www.drupal.org/project/euccx/issues/3092522 1750 // If the user has already accepted the cookies in general (aka from the EU 1751 // Cookie Compliance button) then there is no reason to respect the 1752 // unticked option. For more information on the reasoning behind that 1753 // see: https://www.drupal.org/project/euccx/issues/3109741 1754 if (!cookieValue) { 1755 if (Drupal.settings.euccx.unticked && !Drupal.eu_cookie_compliance.hasAgreed()) { 1756 $('#cookie-tabs input').prop('checked', false); 1757 } 1758 else { 1759 $('#cookie-tabs input').prop('checked', true); 1760 } 1761 } 1762 else { 1763 var plugins = Drupal.settings.euccx.plugins; 1764 for (var key in plugins) { 1765 if ({}.hasOwnProperty.call(plugins, key)) { 1766 var input = $("input[name*='" + key + "']"); 1767 if (input.length && (cookieValue.indexOf(key) !== -1)) { 1768 input.prop('checked', true); 1769 } 1770 } 1771 } 1772 } 1773 }; 1774 1775 /** 1776 * Handles the switches if eucc opt-in with categories is used. 1777 * In this case the switches are simple indicatory for the eucc category 1778 * status. 1779 */ 1780 Drupal.euccx.handleCategorySwitches = function () { 1781 // Open the cookie popup whenever a pseudo switch is clicked. 1782 $("#cookie-tabs .euccx-slider").click(Drupal.eu_cookie_compliance.toggleWithdrawBanner); 1783 1784 // Mark plugins from allowed categories as active (passively): 1785 var plugins = Drupal.euccx.getAcceptedCategoriesPluginNames(); 1786 for (var i = 0; i < plugins.length; i++) { 1787 var currentPlugin = plugins[i]; 1788 var $aliasSlider = $("#cookie-tabs .euccx-slider.euccx-slider-" + currentPlugin); 1789 if ($aliasSlider.length > 0) { 1790 $aliasSlider.addClass('euccx-slider-checked'); 1791 } 1792 } 1793 }; 1794 1795 // Check our settings for cookies that plugins declared as being offensive. 1796 // If the pluginName is empty, return offending cookies from all enabled 1797 // plugins. 1798 // Note: this function screens out non-enabled plugins. 1799 Drupal.euccx.getOffendingCookies = function (pluginName) { 1800 var offendingCookies = []; 1801 var settings = Drupal.settings.euccx; 1802 var pluginNames = Drupal.euccx.getPluginNames(); 1803 for (var i = 0; i < pluginNames.length; i++) { 1804 var currentPlugin = pluginNames[i]; 1805 var cookies_handled = false; 1806 if (settings['plugins'] && settings['plugins'][currentPlugin] && 1807 settings['plugins'][currentPlugin]['cookies_handled']) { 1808 cookies_handled = settings['plugins'][currentPlugin]['cookies_handled']; 1809 } 1810 1811 // The below check translates to: if the plugin uses the cookies_handled 1812 // key AND it's an array AND (either this function was called for all 1813 // plugins or the plugin that it was called for is the one we're 1814 // checking right now), add the offending cookies to our array. 1815 if (cookies_handled && cookies_handled.constructor === Array && 1816 (pluginName === '' || pluginName === pluginNames[i])) { 1817 offendingCookies = offendingCookies.concat(cookies_handled); 1818 } 1819 } 1820 return offendingCookies; 1821 }; 1822 1823 // We remove the offending cookies by setting their expiration date to the 1824 // past and their content to "null". 1825 // This is very similar to the functionality provided by the EU Cookie 1826 // Compliance module. The core differences are: 1827 // 1) Since the new version of jquery.cookie that you get through 1828 // jquery_update does not support removeCookie but instead allows you to 1829 // remove cookies by setting their value to null, we are using this new method 1830 // as fallback and are also setting the expiration date to the past. 1831 // 2) Since some cookies may be registered in both the subdomain but also the 1832 // root domain, we are blanket-replacing the cookie names that were defined by 1833 // our plugins. 1834 Drupal.behaviors.euccxRemoveOffendingCookies = { 1835 attach: function (context, settings) { 1836 $(document).ready(function () { 1837 var status = Drupal.euccx.getCookieStatus();
1838 var offendingCookies = []; 1839 // Check if there is an EU Cookie Compliance cookie. If there is not, 1840 // all cookies defined in our plugins, should be considered offending 1841 // cookies because the user has not agreed to anything yet. 1842 if (!status['cookie-eucc']) { 1843 offendingCookies = Drupal.euccx.getOffendingCookies(''); 1844 } 1845 // If there is no euccx cookies but there is an eucc cookie, it means 1846 // that the user agreed to everything. However, if there is an eucc and 1847 // an euccx cookie, we need to dig a little deeper. 1848 else if (status['cookie-euccx']) { 1849 var pluginNames = Drupal.euccx.getPluginNames(); 1850 for (let i = 0; i < pluginNames.length; i++) { 1851 var currentPlugin = pluginNames[i]; 1852 // We only push the offending cookies of the current plugin, if the 1853 // plugin name is absent from our cookie. 1854 if (status['cookie-euccx'].indexOf(currentPlugin) === -1) { 1855 offendingCookies = 1856 Drupal.euccx.getOffendingCookies(currentPlugin); 1857 } 1858 } 1859 } 1860 // Loop through any offending cookie names that we've found above 1861 for (let i = 0; i < offendingCookies.length; i++) { 1862 var hostname = window.location.hostname; 1863 var index = 0; 1864 var ctd = offendingCookies[i]; 1865 while (hostname !== '') { 1866 // Check if jQuery.removeCookie is available: 1867 if (typeof $.removeCookie !== typeof undefined) { 1868 // jQuery.removeCookie exists! 1869 // Remove the cookie entirely: 1870 $.removeCookie(ctd, { 1871 path: '/', 1872 domain: '.' + hostname 1873 }); 1874 $.removeCookie(ctd, { 1875 path: '/', 1876 domain: hostname 1877 }); 1878 } else { 1879 // Fallback if jQuery.removeCookie is not available. 1880 // Set the cookies content to null. 1881 // Only set the value if the cookie exists, otherwise we'd 1882 // create a new empty cookie here: 1883 if ($.cookie(ctd) !== typeof undefined) { 1884 // For subdomain: 1885 $.cookie(ctd, null, { 1886 expires: -5, 1887 domain: '.' + hostname, 1888 path: '/'} 1889 ); 1890 // For domain: 1891 $.cookie(ctd, null, { 1892 expires: -5, 1893 domain: hostname, 1894 path: '/'} 1895 ); 1896 } 1897 } 1898 index = hostname.indexOf('.'); 1899 hostname = (index === -1) ? '' : hostname.substring(index + 1); 1900 } 1901 } 1902 }); 1903 } 1904 }; 1905})(jQuery); 1906;
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.