1/*! 2 * ihavecookies - jQuery plugin for displaying cookie/privacy message 3 * v0.3.2 4 * 5 * Copyright (c) 2018 Ketan Mistry (https://iamketan.com.au) 6 * Licensed under the MIT license: 7 * http://www.opensource.org/licenses/mit-license.php 8 * 9 */ 10(function($) { 11 12 /* 13 |-------------------------------------------------------------------------- 14 | Cookie Message 15 |-------------------------------------------------------------------------- 16 | 17 | Displays the cookie message on first visit or 30 days after their 18 | last visit. 19 | 20 | @param event - 'reinit' to reopen the cookie message 21 | 22 */ 23 $.fn.ihavecookies = function(options, event) { 24 25 var $element = $(this); 26 27 // Set defaults 28 var settings = $.extend({ 29 cookieTypes: [ 30 { 31 type: 'Site Preferences', 32 value: 'preferences', 33 description: 'These are cookies that are related to your site preferences, e.g. remembering your username, site colours, etc.' 34 }, 35 { 36 type: 'Analytics', 37 value: 'analytics', 38 description: 'Cookies related to site visits, browser types, etc.' 39 }, 40 { 41 type: 'Marketing', 42 value: 'marketing', 43 description: 'Cookies related to marketing, e.g. newsletters, social media, etc' 44 } 45 ], 46 title: 'Cookies & Privacy', 47 message: 'Cookies enable you to use shopping carts and to personalize your experience on our sites, tell us which parts of our websites people have visited, help us measure the effectiveness of ads and web searches, and give us insights into user behavior so we can improve our communications and products.', 48 link: '/privacy-policy', 49 delay: 2000, 50 expires: 30, 51 moreInfoLabel: 'More information', 52 acceptBtnLabel: 'Accept Cookies', 53 advancedBtnLabel: 'Customise Cookies', 54 cookieTypesTitle: 'Select cookies to accept', 55 fixedCookieTypeLabel:'Necessary', 56 fixedCookieTypeDesc: 'These are cookies that are essential for the website to work correctly.', 57 onAccept: function(){}, 58 uncheckBoxes: false 59 }, options); 60 61 var myCookie = getCookie('cookieControl'); 62 var myCookiePrefs = getCookie('cookieControlPrefs'); 63 if (!myCookie || !myCookiePrefs || event == 'reinit') { 64 // Remove all instances of the cookie message so it's not duplicated 65 $('#gdpr-cookie-message').remove(); 66 67 // Set the 'necessary' cookie type checkbox which can not be unchecked 68 var cookieTypes = '<li><input type="checkbox" name="gdpr[]" value="necessary" checked="checked" disabled="disabled"> <label title="' + settings.fixedCookieTypeDesc + '">' + settings.fixedCookieTypeLabel + '</label></li>'; 69 70 // Generate list of cookie type checkboxes 71 preferences = JSON.parse(myCookiePrefs); 72 $.each(settings.cookieTypes, function(index, field) { 73 if (field.type !== '' && field.value !== '') { 74 var cookieTypeDescription = ''; 75 if (field.description !== false) { 76 cookieTypeDescription = ' title="' + field.description + '"'; 77 } 78 cookieTypes += '<li><input type="checkbox" id="gdpr-cookietype-' + field.value + '" name="gdpr[]" value="' + field.value + '" data-auto="on"> <label for="gdpr-cookietype-' + field.value + '"' + cookieTypeDescription + '>' + field.type + '</label></li>'; 79 } 80 }); 81 82 // Display cookie message on page 83 var cookieMessage = '<div id="gdpr-cookie-message"><h4>' + settings.title + '</h4><p>' + settings.message + ' <a href="' + settings.link + '">' + settings.moreInfoLabel + '</a><div id="gdpr-cookie-types" style="display:none;"><h5>' + settings.cookieTypesTitle + '</h5><ul>' + cookieTypes + '</ul></div><p><button id="gdpr-cookie-accept" type="button">' + settings.acceptBtnLabel + '</button><button id="gdpr-cookie-advanced" type="button">' + settings.advancedBtnLabel + '</button></p></div>'; 84 setTimeout(function(){ 85 $($element).append(cookieMessage); 86 $('#gdpr-cookie-message').hide().fadeIn('slow', function(){ 87 // If reinit'ing, open the advanced section of message 88 // and re-check all previously selected options. 89 if (event == 'reinit') { 90 $('#gdpr-cookie-advanced').trigger('click'); 91 $.each(preferences, function(index, field) { 92 $('input#gdpr-cookietype-' + field).prop('checked', true); 93 }); 94 } 95 }); 96 }, settings.delay); 97 98 // When accept button is clicked drop cookie 99 $('body').on('click','#gdpr-cookie-accept', function(){ 100 // Set cookie 101 dropCookie(true, settings.expires); 102 103 // If 'data-auto' is set to ON, tick all checkboxes because 104 // the user hasn't clicked the customise cookies button 105 $('input[name="gdpr[]"][data-auto="on"]').prop('checked', true); 106 107 // Save users cookie preferences (in a cookie!) 108 var prefs = []; 109 $.each($('input[name="gdpr[]"]').serializeArray(), function(i, field){ 110 prefs.push(field.value); 111 });
112 setCookie('cookieControlPrefs', encodeURIComponent(JSON.stringify(prefs)), 365); 113 114 // Run callback function 115 settings.onAccept.call(this); 116 }); 117 118 // Toggle advanced cookie options 119 $('body').on('click', '#gdpr-cookie-advanced', function(){ 120 // Uncheck all checkboxes except for the disabled 'necessary' 121 // one and set 'data-auto' to OFF for all. The user can now 122 // select the cookies they want to accept. 123 $('input[name="gdpr[]"]:not(:disabled)').attr('data-auto', 'off').prop('checked', false); 124 $('#gdpr-cookie-types').slideDown('fast', function(){ 125 $('#gdpr-cookie-advanced').prop('disabled', true); 126 }); 127 }); 128 129 } else { 130 var cookieVal = true; 131 if (myCookie == 'false') { 132 cookieVal = false; 133 } 134 dropCookie(cookieVal, settings.expires); 135 } 136 137 // Uncheck any checkboxes on page load 138 if (settings.uncheckBoxes === true) { 139 $('input[type="checkbox"].ihavecookies').prop('checked', false); 140 } 141 142 }; 143 144 // Method to get cookie value 145 $.fn.ihavecookies.cookie = function() { 146 var preferences = getCookie('cookieControlPrefs'); 147 return JSON.parse(preferences); 148 }; 149 150 // Method to check if user cookie preference exists 151 $.fn.ihavecookies.preference = function(cookieTypeValue) { 152 var control = getCookie('cookieControl'); 153 var preferences = getCookie('cookieControlPrefs'); 154 preferences = JSON.parse(preferences); 155 if (control === false) { 156 return false; 157 } 158 if (preferences === false || preferences.indexOf(cookieTypeValue) === -1) { 159 return false; 160 } 161 return true; 162 }; 163 164 /* 165 |-------------------------------------------------------------------------- 166 | Drop Cookie 167 |-------------------------------------------------------------------------- 168 | 169 | Function to drop the cookie with a boolean value of true. 170 | 171 */ 172 var dropCookie = function(value, expiryDays) { 173 setCookie('cookieControl', value, expiryDays); 174 $('#gdpr-cookie-message').fadeOut('fast', function() { 175 $(this).remove(); 176 }); 177 }; 178 179 /* 180 |-------------------------------------------------------------------------- 181 | Set Cookie 182 |-------------------------------------------------------------------------- 183 | 184 | Sets cookie with 'name' and value of 'value' for 'expiry_days'. 185 | 186 */ 187 var setCookie = function(name, value, expiry_days) { 188 var d = new Date(); 189 d.setTime(d.getTime() + (expiry_days*24*60*60*1000)); 190 var expires = "expires=" + d.toUTCString(); 191 document.cookie = name + "=" + value + ";" + expires + ";path=/"; 192 return getCookie(name); 193 }; 194 195 /* 196 |-------------------------------------------------------------------------- 197 | Get Cookie 198 |-------------------------------------------------------------------------- 199 | 200 | Gets cookie called 'name'. 201 | 202 */ 203 var getCookie = function(name) { 204 var cookie_name = name + "="; 205 var decodedCookie = decodeURIComponent(document.cookie); 206 var ca = decodedCookie.split(';'); 207 for (var i = 0; i < ca.length; i++) { 208 var c = ca[i]; 209 while (c.charAt(0) == ' ') { 210 c = c.substring(1); 211 } 212 if (c.indexOf(cookie_name) === 0) { 213 return c.substring(cookie_name.length, c.length); 214 } 215 } 216 return false; 217 }; 218 219}(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.