1/* 2 * @package Cookie Confirm 3 * @author Jurian Even 4 * @link http://www.twentronix.com 5 * @copyright Copyright © 2012-2013 Twentronix. All rights reserved. 6 * @license GNU GPLv3 <http://www.gnu.org/licenses/gpl.html> or (at your option) later. 7 */ 8 9(function($) { 10ccm = 11{ 12 closingModal:false, 13 cookieState:'', 14 hasSetupMobile:false, 15 initComplete:false, 16 isMobile:false, 17 jQueryAttempts:0, 18 noCloseWin:false, 19 setupComplete:false, 20 settings:{ 21 // Populated by initialise() 22 }, 23 strings:{ 24 // Populated by initialise() 25 }, 26 27 initialise: function(obj) { 28 if (obj.settings !== undefined) { 29 for (var attrname in obj.settings) { 30 this.settings[attrname] = obj.settings[attrname]; 31 } 32 } 33 if (obj.strings !== undefined) { 34 for (var attrname in obj.strings) { 35 this.strings[attrname] = obj.strings[attrname]; 36 } 37 } 38 ccm.initComplete = obj; 39 40 ccm.getCookieState(); 41 var showGUI = true; 42 if(ccm.cookieState == 'cookies-undefined' && ccm.settings.autoConsent != 'disabled') { 43 showGUI = ccm.autoConsent(); 44 } 45 46 if(showGUI) { 47 ccm.showGUI(); 48 } 49 50 $(document).on('keyup', ccm.onKeyUp); 51 }, 52 53 initConsentButtons: function() 54 { 55 $('.ccm-js-btn-accept' ).click(function() {ccm.onConsentGiven('yes');}); 56 $('.ccm-js-btn-decline').click(function() {ccm.onConsentGiven('no');}); 57 }, 58 59 setup: function() { 60 ccm.setupComplete = true; 61 }, 62 63 /** 64 * Auto accept/decline cookies 65 * 66 * @returns {boolean} Do we need to execute showGUI()? 67 */ 68 autoConsent: function() 69 { 70 // Only execute in main window, not in iframes 71 if(self!=top) { 72 return false; 73 } 74 75 if(ccm.settings.consentType == 'explicit' && ccm.settings.autoConsent == 'accept') { 76 console.log('Auto accepting of cookies is not allowed with explicit consent!'); 77 return false; 78 } 79 80 if(ccm.getCookie('ccm_autoconsent') == '1') { 81 ccm.deleteCookie('ccm_autoconsent', ccm.settings.consentCookieDomain) 82 // Prevent endless refresh loops, which can happen if cookie can't be deleted, e.g. if it's 83 // previously set to incorrect domain, by only executing auto consent when the cookie could be deleted. 84 if(ccm.getCookie('ccm_autoconsent') != '1') { 85 var cookieValue = ''; 86 switch(ccm.settings.autoConsent) { 87 case 'accept': 88 cookieValue = 'yes'; 89 break; 90 case 'decline': 91 cookieValue = 'no'; 92 break; 93 default: 94 alert('Invalid value for ccm.settings.autoConsent!'); 95 return false; 96 } 97 ccm.setConsentCookieAjax('ccm_cookies_accepted', cookieValue); 98 return false; 99 } 100 } else { 101 ccm.setCookie('ccm_autoconsent', 1, null, ccm.settings.consentCookieDomain); 102 } 103 return true; 104 }, 105 106 /** 107 * Handles Escape button 108 */ 109 onKeyUp: function(e) { 110 if (e.keyCode == 27) { 111 if ($('#ccm-tag').is(":visible")) { 112 ccm.closeModal(); 113 } else{ 114 ccm.hideBanner(); 115 ccm.setConsentCookieAjax('ccm_cookies_accepted', 'no'); 116 } 117 } 118 }, 119 120 onConsentGiven: function(cookieValue) { 121 ccm.hideBanner(); 122 ccm.setConsentCookieAjax('ccm_cookies_accepted', cookieValue); 123 }, 124 125 showGUI: function() { 126 ccm.getCookieState(); 127 if ($('#ccm').length == 0) { 128 $('body').prepend('<div id="ccm"></div>'); 129 } 130 131 if (ccm.cookieState == 'cookies-undefined') { 132 if (ccm.settings.notificationType == 'banner') { 133 ccm.showBanner(); 134 } else { 135 ccm.showPrivacySettings(); 136 ccm.showModal(true); 137 } 138 } else { 139 ccm.showPrivacySettings(); 140 } 141 }, 142 143 getMessages: function() { 144 if (ccm.cookieState == 'cookies-accepted') { 145 ccm.strings.introText = ccm.parseUBB(ccm.strings.introTextAccepted); 146 } else if (ccm.cookieState == 'cookies-declined') { 147 ccm.strings.introText = ccm.parseUBB(ccm.strings.introTextDeclined); 148 } else { 149 ccm.strings.introText = ccm.parseUBB(ccm.strings.introText); 150 } 151 if(ccm.settings.showFullText == true) { 152 ccm.strings.fullText = ccm.parseUBB(ccm.strings.fullText); 153 } 154 if(ccm.settings.showPolicyText == true) { 155 ccm.strings.policyText = ccm.parseUBB(ccm.strings.policyText); 156 } 157 }, 158 159 parseUBB: function($str) 160 { 161 $search = [ 162 ///\[url\=(.*) target\=(.*)\](.*)\[\/url\]/ig, 163 /\[url\=(.*)\](.*)\[\/url\]/ig, 164 /\[policylink\](.*?)\[\/policylink\]/ig, 165 /\[b\](.*?)\[\/b\]/ig, 166 /\[i\](.*?)\[\/i\]/ig 167 ]; 168 169 $replace = [ 170 //'<a href="$1" target="$2" rel="nofollow">$3</a>', 171 '<a href="$1" rel="nofollow">$2</a>', 172 '<a href="'+ccm.strings.cookiePolicyLinkURL+'" rel="nofollow">$1</a>', 173 '<strong>$1</strong>', 174 '<em>$1</em>' 175 ]; 176 177 for (var i=0; i<$search.length; i++) { 178 $str = $str.replace($search[i], $replace[i]); 179 } 180 181 return $str; 182 }, 183 184 getCookie: function(name) { 185 var i, x, y, cookies = document.cookie.split(";"); 186 for (i = 0; i < cookies.length; i++) { 187 x = cookies[i].substr(0, cookies[i].indexOf("=")); 188 y = cookies[i].substr(cookies[i].indexOf("=") + 1); 189 x = x.replace(/^\s+|\s+$/g, ""); 190 if (x == name) { 191 return unescape(y); 192 } 193 } 194 return null; 195 }, 196 197 getConsentCookie: function() { 198 return ccm.getCookie('ccm_cookies_accepted'); 199 }, 200 201 getCookieState: function() { 202 var cookieValue = ccm.getConsentCookie(); 203 switch(cookieValue) { 204 case 'yes': 205 ccm.cookieState = 'cookies-accepted'; 206 break; 207 case 'no': 208 ccm.cookieState = 'cookies-declined'; 209 break; 210 default: 211 ccm.cookieState = 'cookies-undefined'; 212 } 213 }, 214 215 setCookie: function(name, value, seconds, domain) { 216 var expires = ''; 217 var domainString = ''; 218 if (seconds) { 219 var date = new Date(); 220 date.setTime(seconds*1000); 221 expires = '; expires='+date.toGMTString(); 222 } 223 if(domain) { 224 domainString = '; domain='+domain; 225 } 226 document.cookie = name+"="+value+expires+"; path=/"+domainString; 227 }, 228 229 deleteCookie: function(name, domain) { 230 var domainString = ''; 231 if(domain) { 232 domainString = '; domain='+domain; 233 } 234 document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/'+domainString; 235 }, 236 237 /** 238 * Set a cookie if the visitor has a valid session token and send consent to server which logs it (if enabled) 239 */ 240 setConsentCookieAjax: function(name, value) { 241 var consentCookie = ccm.getConsentCookie(); 242 var postContext = {name:name, value:value}; 243 var url = ccm.settings.postUrl; 244 245 // Internet Explorer fix 246 var randomJunk = new Date().getTime(); 247 url += '&randomJunk='+randomJunk; 248 249 ccm.deleteCookie('ccm_autoconsent', ccm.settings.consentCookieDomain); 250 251 // Don't set a cookie or send consent if consent value didn't change 252 if (consentCookie == value) { 253 return; 254 } 255 256 // Only reload when necessarily 257 var reload = true; 258 if((ccm.settings.consentMode == 'optin' && consentCookie == null && value == 'no') || 259 (ccm.settings.consentMode == 'optout' && consentCookie == null && value == 'yes')) { 260 reload = false;
261 } 262 263 var postData = {}; 264 postData[ccm.settings.token] = 1; 265 postData['cookiesAccepted'] = value; 266 267 $.ajax({ 268 type:"POST", 269 url:url, 270 cache:false, 271 contentType:'application/x-www-form-urlencoded; charset=UTF-8', 272 context:postContext, 273 timeout:600000, 274 data:postData 275 }).done(function (msg) { 276 // Initialize 277 var junk = null; 278 var message = ''; 279 280 // Get rid of junk before the data 281 var valid_pos = msg.indexOf('#ccm#'); 282 if( valid_pos == -1 ) { 283 // Valid data not found in the response 284 msg = 'Invalid server response: ' + msg; 285 alert(msg); 286 return; 287 } else if( valid_pos != 0 ) { 288 // Data is prefixed with junk 289 junk = msg.substr(0, valid_pos); 290 message = msg.substr(valid_pos); 291 } 292 else 293 { 294 message = msg; 295 } 296 // Remove triple hash in the beginning 297 message = message.substr(5); 298 299 // Get rid of junk after the data 300 var valid_pos = message.lastIndexOf('#ccm#'); 301 message = message.substr(0, valid_pos); 302 303 try { 304 var data = JSON.parse(message); 305 } catch(err) { 306 var msg = err.message + message; 307 alert(msg); 308 return; 309 } 310 ccm.setConsentCookieSuccessCallback(data, reload); 311 }).fail(function (jqXHR, textStatus, errorThrown) { 312 alert("AJAX Request failed: " + errorThrown + ' ' + textStatus + ". Please try again."); 313 console.log('Error: Cookie Confirm failed AJAX request.'); 314 console.log(errorThrown); 315 console.log(jqXHR); 316 ccm.setConsentCookieFailCallback(); 317 }); 318 }, 319 320 setConsentCookieSuccessCallback: function(data, reload) 321 { 322 if (data['validToken'] == false) { 323 ccm.setConsentCookieFailCallback(); 324 return; 325 } 326 327 ccm.setCookie(data['name'], data['value'], data['expire'], data['domain']); 328 329 // Check if the cookie has been set successfully 330 var setCookieFailed = ccm.getCookie(data['name']) === null; 331 if (setCookieFailed) { 332 alert('Could not accept or decline cookies. Please check your browser settings.'); 333 } 334 335 if(reload) { 336 setTimeout("location.reload(true);", 50); 337 } else { 338 ccm.showGUI(); 339 } 340 }, 341 342 setConsentCookieFailCallback: function() 343 { 344 // Error, normally due to invalid token. Refresh and send this to the server, which shows an error 345 var url = window.location.href; 346 var glue = (url.indexOf('?') == -1) ? '?' : '&'; 347 window.location = url + glue + "ccm_invalidtoken=1"; 348 }, 349 350 showBanner: function() { 351 $('#ccm-tag').fadeOut(null, function () { 352 $(this).remove(); 353 }); 354 ccm.getMessages(); 355 356 var expand = ''; 357 var fullText = ''; 358 var policyText = ''; 359 360 if(ccm.settings.showFullText == true && ccm.strings.fullText != '') { 361 fullText = '<div class="ccm-banner-fulltext ccm-clear">'+ccm.strings.fullText+'</div>'; 362 } 363 if(ccm.settings.showPolicyText == true && ccm.strings.policyText != '') { 364 policyText = '<div class="ccm-banner-policytext ccm-clear">'+ccm.strings.policyText+'</div>'; 365 } 366 if ((ccm.settings.showFullText == true) || (ccm.settings.showPolicyText == true)) { 367 expand = ' <a href="#" id="ccm-banner-expand">' +ccm.strings.readMore+ '...</a>'; 368 } 369 370 var html = 371 '<div id="ccm-banner-wrap">'+ 372 '<div id="ccm-banner">'+ 373 '<div class="ccm-banner-text">'+ 374 '<div class="ccm-banner-introtext ccm-clear">'+ccm.strings.introText + expand +'</div>'+ 375 '<div class="ccm-banner-expanded">'+ fullText + policyText + '</div>'+ 376 '</div>'+ 377 '<div class="ccm-banner-buttons">'+ 378 '<button class="ccm-btn ccm-js-btn-decline ccm-btn-decline ccm-btn-banner-decline">' + ccm.strings.declineCookies + '</button>' + 379 '<button class="ccm-btn ccm-js-btn-accept ccm-btn-accept ccm-btn-banner-accept"></button>' + 380 '</div>'+ 381 '</div>'+ 382 '</div>'; 383 $('#ccm').prepend(html).addClass(ccm.settings.bannerPosition).addClass('ccm-banner-'+ccm.settings.bannerSize); 384 385 if(ccm.settings.showDeclineButton == false) { 386 $('.ccm-btn-banner-decline').hide(); 387 } 388 389 if (ccm.settings.consentMode == 'optout') { 390 $('.ccm-btn-banner-accept').html(ccm.strings.optoutAcceptCookies); 391 } else { 392 $('.ccm-btn-banner-accept').html(ccm.strings.optinAcceptCookies); 393 } 394 395 if (ccm.isMobile) { 396 $('#ccm-banner-wrap').addClass("ccm-mobile"); 397 ccm.setupForMobile(); 398 } 399 400 // Animate readmore 401 $('#ccm-banner-expand').click(function () { 402 if ($(this).html() == ccm.strings.readMore + '...') { 403 $(this).html(ccm.strings.readLess); 404 } else { 405 $(this).html(ccm.strings.readMore + '...'); 406 } 407 $('.ccm-banner-expanded').slideToggle(); 408 return false;
409 }); 410 411 // Animate banner 412 if (!ccm.isMobile) { 413 if (ccm.settings.bannerPosition == "ccm-top-push") { 414 bannerh = $('#ccm-banner-wrap').outerHeight(); 415 $('html').delay(100).animate({marginTop:bannerh}, 1000); 416 417 $(window).resize(function () { 418 $('html').css("margin-top", function () { 419 return $('#ccm-banner-wrap').outerHeight(); 420 }); 421 }); 422 } 423 $('#ccm-banner-wrap').delay(50).slideDown(800); 424 } 425 }, 426 427 hideBanner: function() { 428 if (!ccm.isMobile) { 429 $('#ccm-banner-wrap').fadeOut(1500); 430 if (ccm.settings.bannerPosition == "ccm-top-push") { 431 $('html').animate({marginTop:0}, 400); 432 } 433 } 434 }, 435 436 showPrivacySettings: function() { 437 if ($('#ccm-tag').length != 0) { 438 return; 439 } 440 ccm.getMessages(); 441 442 var tagClass = ccm.cookieState; 443 if(ccm.cookieState == 'cookies-undefined') { 444 tagClass = 'cookies-declined'; 445 } 446 var html = 447 '<div id="ccm-tag">' + 448 '<button id="ccm-btn-tag" class="ccm-js-btn-tag ccm-tag-'+tagClass+'" title="'+ccm.strings.privacySettings+'"></button>' + 449 '</div>'; 450 $('#ccm').prepend(html).addClass('ccm-'+ccm.settings.tagPosition); 451 452 if (ccm.settings.showPrivacySettings == true) { 453 $('#ccm-tag').show(); 454 } else { 455 $('#ccm-tag').hide(); 456 } 457 $('.ccm-js-btn-tag').click(ccm.showModal); 458 }, 459 460 showModal: function(reload) { 461 typeof reload !== 'undefined' ? reload : false; 462 463 ccm.getCookieState(); 464 $('.ccm-js-btn-tag').off('click').on('click', ccm.toggleModal); 465 466 $(this).blur(); 467 if (ccm.isMobile) { 468 ccm.setupForMobile(); 469 } 470 471 ccm.getMessages(); 472 473 var mExpanded = ''; 474 if(ccm.settings.showFullText == true || ccm.settings.showPolicyText == true) { 475 mExpanded += '<div class="ccm-modal-expanded">'; 476 if(ccm.settings.showFullText == true && ccm.strings.fullText != '') { 477 mExpanded += '<div class="ccm-modal-fulltext ccm-clear">' + ccm.strings.fullText + '</div>'; 478 } 479 if(ccm.settings.showPolicyText == true && ccm.strings.policyText != '') { 480 mExpanded += '<div class="ccm-modal-policytext ccm-clear">' + ccm.strings.policyText + '</div>'; 481 } 482 mExpanded += '</div>'; 483 } 484 485 var mFooter = ''; 486 if(ccm.settings.showFullText == true || ccm.settings.showPolicyText == true) { 487 mFooter += '<button class="ccm-btn ccm-btn-modal-expand">'+ ccm.strings.readMore +'</button>'; 488 } 489 if(ccm.settings.showCredits == true) { 490 mFooter += '<div class="ccm-modal-credits"><a href="https://www.twentronix.com/extensions/cookieconfirm" target="_blank">'+ccm.strings.aboutThisExtension+'</a></div>'; 491 } 492 493 // Add label and consent buttons 494 var mConsent = ''; 495 var mStatus = ''; 496 if (ccm.cookieState == 'cookies-accepted') { 497 mStatus += '<div class="ccm-modal-status"><span class="ccm-label ccm-label-success">'+ccm.strings.cookiesEnabled+'</span></div>'; 498 mConsent += '<button class="ccm-btn ccm-js-btn-decline ccm-btn-decline ccm-btn-modal-decline">'+ ccm.strings.declineCookies + '</button>'; 499 } else if (ccm.cookieState == 'cookies-declined') { 500 mStatus += '<div class="ccm-modal-status"><span class="ccm-label ccm-label-important">'+ccm.strings.cookiesDisabled+'</span></div>'; 501 mConsent += '<button class="ccm-btn ccm-js-btn-accept ccm-btn-accept ccm-btn-modal-accept">'+ ccm.strings.optinAcceptCookies + '</button>'; 502 } else { 503 mConsent += '<button class="ccm-btn ccm-js-btn-accept ccm-btn-accept ccm-btn-modal-accept">'; 504 mConsent += (ccm.settings.consentMode == 'optout') ? ccm.strings.optoutAcceptCookies : ccm.strings.optinAcceptCookies; 505 mConsent += '</button>'; 506 if(ccm.settings.showDeclineButton == true) { 507 mConsent += '<button class="ccm-btn ccm-js-btn-decline ccm-btn-decline ccm-btn-modal-decline" style="margin-top:10px;">'+ ccm.strings.declineCookies + '</button>'; 508 } 509 } 510 511 var mClass = 'ccm-modal-status-' + ((mStatus == '') ? 'hidden' : 'visible'); 512 var html = 513 '<div id="ccm-modal" class="'+mClass+'">' + 514 '<div class="ccm-modal-inner">' + 515 '<button class="ccm-btn-modal-close" title="' + ccm.strings.closeWindow + '">' + 516 '<div class="ccm-modal-close-bg"></div>'+ 517 '</button>' + 518 '<div class="ccm-modal-header">' + 519 '<h3 class="ccm-modal-title">' + ccm.strings.privacySettings + '</h3>' + 520 '</div>' + 521 '<div class="ccm-modal-body">' + 522 '<div class="ccm-modal-introtext ccm-clear">' + ccm.strings.introText + '</div>' + 523 mExpanded + 524 '</div>' + 525 '<div class="ccm-modal-footer">' + mFooter + '</div>' + 526 '<div class="ccm-modal-consent">' + mConsent + '</div>'+ 527 '</div>' + 528 mStatus; 529 $('#ccm-modal').remove(); 530 $(html).hide().prependTo('#ccm').fadeIn(200); 531 532 // Expand 533 $('.ccm-btn-modal-expand').click(function () { 534 if ($('.ccm-modal-expanded').is(":visible")) { 535 $('.ccm-btn-modal-expand').html(ccm.strings.readMore); 536 } else { 537 $('.ccm-btn-modal-expand').html(ccm.strings.readLess); 538 } 539 $('.ccm-modal-expanded').slideToggle(); 540 }); 541 542 if (ccm.isMobile) { 543 $('#ccm-modal').addClass("ccm-mobile"); 544 } 545 546 ccm.initConsentButtons(); 547 $('.ccm-btn-modal-close, .ccm-btn-modal-accept, .ccm-btn-modal-decline').click(function () { 548 ccm.toggleModal(); 549 if(reload == true && ccm.cookieState == 'cookies-undefined') { 550 $('.ccm-js-btn-tag').off('click').on('click', function(){(ccm.showModal(true))}); 551 } 552 }); 553 }, 554 555 toggleModal: function() { 556 ccm.closingModal = true; 557 $('#ccm-modal').fadeToggle(200, function() { 558 ccm.closingModal = false;
559 }); 560 }, 561 562 closeModal: function() { 563 if (!ccm.closingModal) { 564 if (ccm.noCloseWin) { 565 ccm.noCloseWin = false; 566 } else if ($('#ccm-modal').is(":visible")) { 567 $('.ccm-btn-modal-close').click(); 568 } 569 } 570 }, 571 572 setupForMobile: function() { 573 if (!ccm.hasSetupMobile) { 574 $('head').append('<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0;">'); 575 $('body').html('').css("margin", 0); 576 ccm.hasSetupMobile = true; 577 } 578 }, 579 580 onFirstLoad: function() { 581 if (!ccm.setupComplete && ccm.initComplete) { 582 if (!(window.jQuery)) { 583 ccm.jQueryAttempts++; 584 if (ccm.jQueryAttempts >= 5) { 585 return; 586 } 587 setTimeout(ccm.onFirstLoad, 200); 588 return; 589 } 590 ccm.setup(); 591 } 592 setTimeout(ccm.afterLoad, 50); 593 }, 594 595 afterLoad: function() { 596 ccm.initConsentButtons(); 597 } 598}; 599$(document).ready(ccm.onFirstLoad); 600})(akeeba.jQuery);
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.