1/* 2 * Based on Cookie Consent by silktide 3 */ 4 5(function () { 6 // Stop from running again, if accidently included more than once. 7 if (window.hasCookieConsent) return; 8 window.hasCookieConsent = true; 9 10 /* 11 Constants 12 */ 13 14 // Client variable which may be present containing options to override with 15 var OPTIONS_VARIABLE = 'cookieconsent_options'; 16 17 // Change cookie consent options on the fly. 18 var OPTIONS_UPDATER = 'update_cookieconsent_options'; 19 20 // Name of cookie to be set when dismissed 21 var DISMISSED_COOKIE = 'cookieconsent_dismissed'; 22 23 // The path to built in themes (s3 bucket) 24 var THEME_BUCKET_PATH = '//s3.amazonaws.com/cc.silktide.com/'; 25 26 // No point going further if they've already dismissed. 27 if (document.cookie.indexOf(DISMISSED_COOKIE) > -1) { 28 return; 29 } 30 31 // IE8... 32 if (typeof String.prototype.trim !== 'function') { 33 String.prototype.trim = function () { 34 return this.replace(/^\s+|\s+$/g, ''); 35 }; 36 } 37 38 /* 39 Helper methods 40 */ 41 var Util = { 42 isArray: function (obj) { 43 var proto = Object.prototype.toString.call(obj); 44 return proto == '[object Array]'; 45 }, 46 47 isObject: function (obj) { 48 return Object.prototype.toString.call(obj) == '[object Object]'; 49 }, 50 51 each: function (arr, callback, /* optional: */context, force) { 52 if (Util.isObject(arr) && !force) { 53 for (var key in arr) { 54 if (arr.hasOwnProperty(key)) { 55 callback.call(context, arr[key], key, arr); 56 } 57 } 58 } else { 59 for (var i = 0, ii = arr.length; i < ii; i++) { 60 callback.call(context, arr[i], i, arr); 61 } 62 } 63 }, 64 65 merge: function (obj1, obj2) { 66 if (!obj1) return; 67 Util.each(obj2, function (val, key) { 68 if (Util.isObject(val) && Util.isObject(obj1[key])) { 69 Util.merge(obj1[key], val); 70 } else { 71 obj1[key] = val; 72 } 73 }) 74 }, 75 76 bind: function (func, context) { 77 return function () { 78 return func.apply(context, arguments); 79 }; 80 }, 81 82 /* 83 find a property based on a . separated path. 84 i.e. queryObject({details: {name: 'Adam'}}, 'details.name') // -> 'Adam' 85 returns null if not found 86 */ 87 queryObject: function (object, query) { 88 var queryPart; 89 var i = 0; 90 var head = object; 91 query = query.split('.'); 92 while ((queryPart = query[i++]) && head.hasOwnProperty(queryPart) && (head = head[queryPart])) { 93 if (i === query.length) return head; 94 } 95 return null; 96 }, 97 98 setCookie: function (name, value, expiryDays, domain, path) { 99 expiryDays = expiryDays || 365; 100 101 var exdate = new Date(); 102 exdate.setDate(exdate.getDate() + expiryDays); 103 104 var cookie = [ 105 name + '=' + value, 106 'expires=' + exdate.toUTCString(), 107 'path=' + path || '/' 108 ]; 109 110 if (domain) { 111 cookie.push( 112 'domain=' + domain 113 ); 114 } 115 116 document.cookie = cookie.join(';'); 117 }, 118 119 addEventListener: function (el, event, eventListener) { 120 if (el.addEventListener) { 121 el.addEventListener(event, eventListener); 122 } else { 123 el.attachEvent('on' + event, eventListener); 124 } 125 } 126 }; 127 128 var DomBuilder = (function () { 129 /* 130 The attribute we store events in. 131 */ 132 var eventAttribute = 'data-cc-event'; 133 var conditionAttribute = 'data-cc-if'; 134 135 /* 136 Shim to make addEventListener work correctly with IE. 137 */ 138 var addEventListener = function (el, event, eventListener) { 139 // Add multiple event listeners at once if array is passed. 140 if (Util.isArray(event)) { 141 return Util.each(event, function (ev) { 142 addEventListener(el, ev, eventListener); 143 }); 144 } 145 146 if (el.addEventListener) { 147 el.addEventListener(event, eventListener); 148 } else { 149 el.attachEvent('on' + event, eventListener); 150 } 151 }; 152 153 /* 154 Replace {{variable.name}} with it's property on the scope 155 Also supports {{variable.name || another.name || 'string'}} 156 */ 157 var insertReplacements = function (htmlStr, scope) { 158 return htmlStr.replace(/\{\{(.*?)\}\}/g, function (_match, sub) { 159 var tokens = sub.split('||'); 160 var value; 161 while (token = tokens.shift()) { 162 token = token.trim(); 163
164 // If string 165 if (token[0] === '"') return token.slice(1, token.length - 1); 166 167 // If query matches 168 value = Util.queryObject(scope, token); 169 170 if (value) return value; 171 } 172 173 return ''; 174 }); 175 }; 176 177 /* 178 Turn a string of html into DOM 179 */ 180 var buildDom = function (htmlStr) { 181 var container = document.createElement('div'); 182 container.innerHTML = htmlStr; 183 return container.children[0]; 184 }; 185 186 var applyToElementsWithAttribute = function (dom, attribute, func) { 187 var els = dom.parentNode.querySelectorAll('[' + attribute + ']'); 188 Util.each(els, function (element) { 189 var attributeVal = element.getAttribute(attribute); 190 func(element, attributeVal); 191 }, window, true); 192 }; 193 194 /* 195 Parse event attributes in dom and set listeners to their matching scope methods 196 */ 197 var applyEvents = function (dom, scope) { 198 applyToElementsWithAttribute(dom, eventAttribute, function (element, attributeVal) { 199 var parts = attributeVal.split(':'); 200 var listener = Util.queryObject(scope, parts[1]); 201 addEventListener(element, parts[0], Util.bind(listener, scope)); 202 }); 203 }; 204 205 var applyConditionals = function (dom, scope) { 206 applyToElementsWithAttribute(dom, conditionAttribute, function (element, attributeVal) { 207 var value = Util.queryObject(scope, attributeVal); 208 if (!value) { 209 element.parentNode.removeChild(element); 210 } 211 }); 212 }; 213 214 return { 215 build: function (htmlStr, scope) { 216 if (Util.isArray(htmlStr)) htmlStr = htmlStr.join(''); 217 218 htmlStr = insertReplacements(htmlStr, scope); 219 var dom = buildDom(htmlStr); 220 applyEvents(dom, scope); 221 applyConditionals(dom, scope); 222 223 return dom; 224 } 225 }; 226 })(); 227 228 229 /* 230 Plugin 231 */ 232 var cookieconsent = { 233 options: { 234 message: 'This website uses cookies to ensure you get the best experience on our website. ', 235 dismiss: 'Got it!', 236 learnMore: 'More info', 237 link: null, 238 container: null, // selector 239 theme: 'light-floating', 240 domain: null, // default to current domain. 241 path: '/', 242 expiryDays: 365, 243 markup: [ 244 '<div id="cc_banner" class="cc_banner-wrapper {{containerClasses}}">', 245 '<div class="cc_banner cc_container cc_container--open">', 246 '<a href="" data-cc-event="click:dismiss" rel="nofollow" class="cc_btn cc_btn_accept_all">{{options.dismiss}}</a>', 247 248 '<p class="cc_message">{{options.message}} <a data-cc-if="options.link" class="cc_more_info" href="{{options.link || "#null"}}">{{options.learnMore}}</a></p>', 249 250 '', 251 '</div>', 252 '</div>' 253 ], 254 appendToBottom: 0 255 }, 256 257 init: function () { 258 var options = window[OPTIONS_VARIABLE]; 259 if (options) this.setOptions(options); 260 261 if (this.options.appendToBottom) { 262 window.addEventListener("load", function () { 263 document.body.classList.add("cookie-padding"); 264 }); 265 } 266 267 this.setContainer(); 268 269 // Calls render when theme is loaded. 270 /* MSH EDIT 271 if (this.options.theme) { 272 this.loadTheme(this.render); 273 } else { 274 this.render(); 275 } 276 */ 277 this.render(); 278 279 window.addEventListener("load", (event) => { 280 const acceptBtn = document.querySelector('.cc_banner-wrapper .cc_btn.cc_btn_accept_all'); 281 const dismissBtn = document.querySelector('.cc_banner-wrapper .cc_btn.cc_btn_dismiss'); 282 283 if (sessionStorage.getItem('cookieconsent_track') == null) { 284 sessionStorage.setItem('cookieconsent_track', 0); 285 } 286 287 let d = new Date(); 288 d.setTime(d.getTime() + (365*24*60*60*1000)); 289 290 if (acceptBtn) { 291 acceptBtn.addEventListener('click', function () { 292 document.cookie = "cookieconsent_track=1;expires=" + d.toUTCString(); 293 location.reload(); 294 }); 295 } 296 if (dismissBtn) {
297 dismissBtn.addEventListener('click', function () { 298 document.cookie = "cookieconsent_track=0;expires=" + d.toUTCString(); 299 location.reload(); 300 }); 301 } 302 }); 303 }, 304 305 setOptionsOnTheFly: function (options) { 306 this.setOptions(options); 307 this.render(); 308 }, 309 310 setOptions: function (options) { 311 Util.merge(this.options, options); 312 }, 313 314 setContainer: function () { 315 if (this.options.container) { 316 this.container = document.querySelector(this.options.container); 317 } else { 318 this.container = document.body; 319 } 320 321 // Add class to container classes so we can specify css for IE8 only. 322 this.containerClasses = ''; 323 if (navigator.appVersion.indexOf('MSIE 8') > -1) { 324 this.containerClasses += ' cc_ie8' 325 } 326 }, 327 328 loadTheme: function (callback) { 329 var theme = this.options.theme; 330 331 // If theme is specified by name 332 if (theme.indexOf('.css') === -1) { 333 theme = THEME_BUCKET_PATH + theme + '.css'; 334 } 335 336 var link = document.createElement('link'); 337 link.rel = 'stylesheet'; 338 link.type = 'text/css'; 339 link.href = theme; 340 341 var loaded = false; 342 link.onload = Util.bind(function () { 343 if (!loaded && callback) { 344 callback.call(this); 345 loaded = true; 346 } 347 }, this); 348 349 document.getElementsByTagName("head")[0].appendChild(link); 350 }, 351 352 render: function () { 353 // remove current element (if we've already rendered) 354 if (this.element && this.element.parentNode) { 355 this.element.parentNode.removeChild(this.element); 356 delete this.element; 357 } 358 359 this.element = DomBuilder.build(this.options.markup, this); 360 if (!this.container.firstChild) { 361 this.container.appendChild(this.element); 362 } else { 363 this.container.insertBefore(this.element, this.container.firstChild); 364 } 365 }, 366 367 dismiss: function (evt) { 368 evt.preventDefault && evt.preventDefault(); 369 evt.returnValue = false; 370 if (this.options.appendToBottom) { 371 document.body.classList.remove("cookie-padding"); 372 } 373 this.setDismissedCookie(); 374 this.container.removeChild(this.element); 375 }, 376 377 setDismissedCookie: function () { 378 Util.setCookie(DISMISSED_COOKIE, 'yes', this.options.expiryDays, this.options.domain, this.options.path); 379 } 380 }; 381 382 var init; 383 var initialized = false; 384 (init = function () { 385 if (!initialized && document.readyState == 'complete') { 386 cookieconsent.init(); 387 initialized = true; 388 window[OPTIONS_UPDATER] = Util.bind(cookieconsent.setOptionsOnTheFly, cookieconsent); 389 } 390 })(); 391 392 Util.addEventListener(document, 'readystatechange', init); 393 394})(); 395 396function getCookieValue(a) { 397 const b = document.cookie.match('(^|;)\\s*' + a + '\\s*=\\s*([^;]+)'); 398 return b ? b.pop() : ''; 399}
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.