(function(window) { 'use strict'; var close = false; var europe = ["AX","DK","EE","FO","FI","GG","IS","IE","JE","IM","LV","LT","NO","SJ","SE","GB","AL","AD","BA","HR","CY","GI","GR","IT","MK","VA","MT","ME","PT","SM","RS","SI","ES","BY","BG","CZ","GE","HU","MD","PL","RO","RU","SK","UA","AT","BE","FR","DE","LI","LU","MC","NL","CH"]; var cookieDesc = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie') || Object.getOwnPropertyDescriptor(HTMLDocument.prototype, 'cookie'); var setter = cookieDesc.set; var getter = cookieDesc.get; var cookiesSet = []; var cookiesBlocked = false; function recordCookieSet(str) { cookiesSet.push(str); return true; } function deleteAllCookies() { var cookies = document.cookie.split(/;\s?/); for (var i = 0; i < cookies.length; i++) { var cookie = cookies[i]; var eqPos = cookie.indexOf("="); var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie; document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT"; } } function blockCookies() { Object.defineProperty(document, 'cookie', { get: function () { return getter.call(document) }, set: recordCookieSet, configurable: true }); cookiesBlocked = true; } function restoreCookies() { Object.defineProperty(document, 'cookie', { get: function () { return getter.call(document) }, set: function (val) { setter.call(document, val) }, }); // Set any cookie set during the enblockening cookiesSet.forEach(c => document.cookie = c); } /** * Retrieves the current users IP Address * @returns {Promise} resolves with the IP and other intel */ function getIntel() { return fetch('https://geoip.internal.commerce.campaignmonitor.com/json/', { method: 'GET' }) .then(function(res) { return res.json(); }) .then(function(data) { return data; }); } /** * Gets the data with the passed name from localStorage * @param {String} name - the name of the property * @returns {String/Boolean/Number} the contents of the storage */ function getData(name) { return localStorage.getItem(name); } /** * Checks if there is relevant data and what it's content are * then checks whether the user has accepted or declined * and returns the result * @param {String} ip - the users current IP * @returns {Object} the has accepted result and ip */ function checkData(ip) { var url = window.location.href; // First check if there is any data stored var acceptCookie = getData('_accept_banner'); var ipCookie = getData('_accept_banner_ip'); // They accepted the banner previously if (acceptCookie) { if (acceptCookie === 'accept') { Cooki.setAccepted(); if (cookiesBlocked) restoreCookies(); } else if (acceptCookie === 'decline') Cooki.setDeclined(); return { showBanner: false, ip: ip }; } // No accept in storage, continue return { showBanner: true, ip: ip }; } /** * Logs the decision and IP to the server * @param {String} choice - 'accept' or 'decline' * @param {String} ip - the users current IP * @returns {Promise} resolves on successfully sent log */ function addLog(choice, ip) { var meta = { choice, notification: '5b05424feb037900143b1556', ip: ip, userAgent: navigator.userAgent, url: window.location.href }; return fetch('https://cookihq.com/log', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(meta) }) .catch(function(e) { console.error('An error occurred while trying to ' + 'record the acceptance of cookies', e); }); } /** * Adds the HTML elements with styles and event listeners * @param {String} ip - the users current IP */ function addNotification(ip, showBanner) { var height = 150; // Add style tag for additional compatibility var styles = document.createElement('style'); styles.type = 'text/css'; var css = '.cooki-description p { color: inherit; }'; if (styles.styleSheet) styles.styleSheet.cssText = css; else styles.appendChild(document.createTextNode(css)); document.body.appendChild(styles); // Create the container of the notification var container = document.createElement('div'); container.style.cssText = 'background:#c1b25f;position:fixed;' + 'left:0px;right:0px;padding:0.5em 1em 1em;font-family:Arial, Helvetica, sans-serif;' + 'z-index: 999;transition: all 0.3s ease-in;'; container.className= 'cooki-container'; var description = document.createElement('div'); description.style.cssText = 'color:#0a0000'; description.innerHTML = '

Why we use cookies: This website uses cookies to deliver the best possible user experience.

'; description.className = 'cooki-description'; container.appendChild(description); var accept = document.createElement('a'); accept.style.cssText = 'border:0px;display:inline-block;padding:8px 20px;' + 'background:#76bd50;border-radius:0.3em;' + 'color:#FFFFFF;cursor:pointer;font-size:1em;' + 'text-decoration:none;'; accept.innerHTML = 'Accept'; accept.className = 'cooki-accept'; accept.addEventListener('click', function() { // Update Height, the screen size could have altered it height = container.clientHeight; Cooki.callAccepted(); if (cookiesBlocked) restoreCookies(); if ('bottom' === 'top') container.style.top = '-' + height + 'px'; else container.style.bottom = '-' + height + 'px'; // Set the data for the accept localStorage.setItem('_accept_banner', 'accept'); localStorage.setItem('_accept_banner_ip', ip); addLog('accept', ip); }); container.appendChild(accept); var decline = document.createElement('a'); decline.style.cssText = 'border:0px;display:inline-block;padding:8px 20px;' + 'background:#a22525;border-radius:0.3em;' + 'color:#FFFFFF;cursor:pointer;margin-left:10px;' + 'font-size:1em;text-decoration:none'; decline.innerHTML = 'Decline'; decline.className = 'cooki-decline'; decline.addEventListener('click', function() { // Update Height, the screen size could have altered it height = container.clientHeight; Cooki.callDeclined(); if ('bottom' === 'top') container.style.top = '-' + height + 'px'; else container.style.bottom = '-' + height + 'px'; // Set the data for the accepts localStorage.setItem('_accept_banner', 'decline'); localStorage.setItem('_accept_banner_ip', ip); addLog('decline', ip); }); container.appendChild(decline); if (true) { var info = document.createElement('a'); info.style.cssText = 'border:0px;display:inline-block;padding:8px 20px;' + 'background:#4a5258;border-radius:0.3em;' + 'color:#FFFFFF;cursor:pointer;margin-left:10px;font-size:1em;' + 'text-decoration:none;'; info.innerHTML = 'More Info'; info.setAttribute('href', 'https://toursafrica.co.za/pages/tours-africa-privacy-policy-2018'); info.setAttribute('target', '_blank'); info.className = 'cooki-info'; container.appendChild(info); } // Append the notification to the body document.body.appendChild(container); height = container.clientHeight; if ('' === 'true') { var tab = document.createElement('a'); tab.style.cssText = 'position:absolute;background:#c1b25f;' + 'display:block;right:30px;padding:5px 10px;color:#0a0000;' + 'cursor:pointer;'; tab.innerText = '' || 'Cookies'; tab.addEventListener('click', function() { if ('bottom' === 'top') container.style.top = '0px'; else container.style.bottom = '0px'; }); container.appendChild(tab); var tabHeight = tab.clientHeight; if ('bottom' === 'top') { tab.style.bottom = '-' + tabHeight + 'px'; tab.style.borderBottomRightRadius = '5px'; tab.style.borderBottomLeftRadius = '5px'; } else { tab.style.top = '-' + tabHeight + 'px'; tab.style.borderTopRightRadius = '5px'; tab.style.borderTopLeftRadius = '5px'; } } if ('bottom' === 'top') { container.style.top = '-' + height + 'px'; if (showBanner) setTimeout(function() { container.style.top = '0px'; }, 10); } else { container.style.bottom = '-' + height + 'px'; if (showBanner) setTimeout(function() { container.style.bottom = '0px'; }, 10); } } function isInEurope(intel) { return europe.indexOf(intel.country_code) > -1; } function CookiAPI() { this.acceptListeners = []; this.declineListeners = []; this.readyListeners = []; this.declined = false; this.accepted = false; this.isInEurope = false; } CookiAPI.prototype.addAcceptListener = function(listener) { this.acceptListeners.push(listener); } CookiAPI.prototype.removeAcceptListener = function(listener) { this.acceptListeners = this.acceptListeners.filter(function(l) { return l !== listener; }); } CookiAPI.prototype.addDeclineListener = function(listener) { this.declineListeners.push(listener); } CookiAPI.prototype.removeDeclineListener = function(listener) { this.declineListeners = this.declineListeners.filter(function(l) { return l !== listener; }); } CookiAPI.prototype.addReadyListener = function(listener) { this.readyListeners.push(listener); } CookiAPI.prototype.removeReadyListener = function(listener) { this.readyListeners = this.readyListeners.filter(function(l) { return l !== listener; }); } CookiAPI.prototype.setAccepted = function() { this.accepted = true; this.declined = false; } CookiAPI.prototype.setDeclined = function() { this.accepted = false; this.declined = true; // Remove all cookies that are currently accessible if ( '' === 'true' || ('' === '' && '' === 'true') ) deleteAllCookies(); } CookiAPI.prototype.callAccepted = function() { this.setAccepted(); this.acceptListeners.forEach(function(listener) { if (listener) listener(); }); } CookiAPI.prototype.callDeclined = function() { this.setDeclined(); this.declineListeners.forEach(function(listener) { if (listener) listener(); }); } CookiAPI.prototype.ready = function() { this.readyListeners.forEach(function(listener) { if (listener) listener(); }); } window.Cooki = new CookiAPI(); if ('' === 'true') blockCookies(); getIntel() .then(function(intel) { var result = isInEurope(intel) Cooki.isInEurope = result; // Check if the notification should be shown (europe) if (true) { // Check whether the country is in europe if (!result) { restoreCookies(); return { showBanner: false, ip: intel.ip, isEurope: result }; } return checkData(intel.ip); } // Check whether the ip has already been registered return checkData(intel.ip); }) .then(function(data) { Cooki.ready(); if (data.isEurope) return; // Add the notification addNotification(data.ip, data.showBanner); }) .catch(function(e) { console.log(e); console.error('An error has occurred when adding the cookie notification', e); }); })(window);