From 1b8a213085f4b55dcf9f69b14bf45707381d17e2 Mon Sep 17 00:00:00 2001 From: Orest Bida Date: Wed, 25 Aug 2021 18:29:45 +0200 Subject: [PATCH 01/17] add eraseCookie() function as API --- src/cookieconsent.js | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/cookieconsent.js b/src/cookieconsent.js index bce20a24..22541ca8 100644 --- a/src/cookieconsent.js +++ b/src/cookieconsent.js @@ -1366,6 +1366,31 @@ _log("CookieConsent [SETTINGS]: hide settings_modal"); } + /** + * API function to easily erase cookies + * @param {(string|string[])} _cookies + * @param {string} _path + * @param {string} _domain + */ + _cookieconsent.eraseCookies = function(_cookies, _path, _domain){ + var cookies = []; + var domains = _domain ? + [_domain, "."+_domain] : + [_config.cookie_domain, "."+_config.cookie_domain]; + + if(_cookies && _cookies.length > 0){ + for(var i=0; i<_cookies.length; i++){ + if(this.validCookie(_cookies[i])){ + cookies.push(_cookies[i]); + } + } + }else{ + cookies = [_cookies]; + } + + _eraseCookies(cookies, _path, domains); + } + /** * Set cookie, by specifying name and value * @param {String} name @@ -1518,7 +1543,9 @@ * to prevent users from directly manipulating the * cookieconsent options from browser console (or at least make it harder) */ - return (CookieConsent = window[init] = undefined), _cookieconsent; + CookieConsent = window[init] = undefined; + + return _cookieconsent; }; var init = 'initCookieConsent'; From cbb7542708a34052a2d0ac48e2031f4905a50d83 Mon Sep 17 00:00:00 2001 From: Orest Bida Date: Wed, 25 Aug 2021 19:45:54 +0200 Subject: [PATCH 02/17] fix jsDoc --- src/cookieconsent.js | 134 ++++++++++++++++++++++++------------------- 1 file changed, 74 insertions(+), 60 deletions(-) diff --git a/src/cookieconsent.js b/src/cookieconsent.js index 22541ca8..17f28109 100644 --- a/src/cookieconsent.js +++ b/src/cookieconsent.js @@ -1,5 +1,5 @@ /*! - * CookieConsent v2.4.7 + * CookieConsent v2.5.0 * https://www.github.com/orestbida/cookieconsent * Author Orest Bida * Released under the MIT License @@ -59,6 +59,7 @@ /** * Array of booleans used to keep track of enabled/disabled preferences + * @type {boolean[]} */ var toggle_states = []; @@ -75,7 +76,7 @@ * @param {Object} conf_params */ var _setConfig = function(conf_params){ - _log("CookieConsent [CONFIG]: recieved_config_settings ", conf_params); + _log("CookieConsent [CONFIG]: received_config_settings ", conf_params); if(typeof conf_params['cookie_expiration'] === "number"){ _config.cookie_expiration = conf_params['cookie_expiration']; @@ -135,11 +136,10 @@ } /** - * Check if given lang. index exists as a property. - * If it exists -> desired language is implemented, - * otherwise fall back to the default current_lang - * @param {String} lang - * @param {Object} all_languages + * Get a valid language (at least 1 must be defined) + * @param {string} lang - desired language + * @param {Object} all_languages - all defined languages + * @returns {string} validated language */ var _getValidatedLanguage = function(lang, all_languages){ if(all_languages.hasOwnProperty(lang)){ @@ -156,17 +156,15 @@ /** * Save reference to first and last focusable elements inside each modal * to prevent losing focus while navigating with TAB - * @param {HTMLElement} modal_dom */ var _getModalFocusableData = function(){ /** * Note: any of the below focusable elements, which has the attribute tabindex="-1" AND is either - * the first or last element of the modal, won't recieve focus during "open/close" modal + * the first or last element of the modal, won't receive focus during "open/close" modal */ var allowed_focusable_types = ['[href]', 'button', 'input', 'details', '[tabindex="0"]']; - function _getAllFocusableElements(modal, _array){ var focus_later=false, focus_first=false; @@ -396,7 +394,7 @@ block_desc.className = 'p'; block_title_container.className = 'title'; - // Sset title and description for each block + // Set title and description for each block block_desc.insertAdjacentHTML('beforeend', all_blocks[i]['description']); // Create toggle if specified (opt in/out) @@ -640,7 +638,7 @@ */ var _saveCookiePreferences = function(conf_params, accept_type){ - // Get all cookiepreferences values saved in cookieconsent settings modal + // Retrieve all toggle/checkbox values var category_toggles = document.querySelectorAll('.c-tgl') || []; var c_cookie_level = '', changedSettings = [], must_reload = false; @@ -813,10 +811,15 @@ } } + /** + * Function to run after css load + * @callback cssLoaded + */ + /** * Load style via ajax in background (and then show modal) - * @param {String} css_path - * @param {Function} callback + * @param {string} css_path + * @param {cssLoaded} callback */ var _loadCSS = function(css_path, callback){ @@ -861,10 +864,10 @@ } /** - * Returns index of found elemet inside array, otherwise -1 + * Returns index of found element inside array, otherwise -1 * @param {Array} arr * @param {Object} value - * @returns {Number} + * @returns {number} */ var _inArray = function(arr, value){ var len = arr.length; @@ -886,7 +889,7 @@ /** * Helper function which creates an HTMLElement object based on 'type' and returns it. - * @param {String} type + * @param {string} type * @returns {HTMLElement} */ var _createNode = function(type){ @@ -899,8 +902,7 @@ /** * Get current client's browser language - * Used when 'auto_language' config property is set to 'true' (boolean) - * @returns {String} + * @returns {string} */ var _getBrowserLang = function(){ var browser_lang = navigator.language || navigator.browserLanguage; @@ -910,7 +912,7 @@ } /** - * Trap focus inside modal and focuse the first + * Trap focus inside modal and focus the first * focusable element of current active modal */ var _handleFocusTrap = function(){ @@ -999,7 +1001,7 @@ */ var _guiManager = function(gui_options){ - // If gui_options is not obje => exit + // If gui_options is not object => exit if(typeof gui_options !== 'object') return; var consent_modal_options = gui_options['consent_modal']; @@ -1010,10 +1012,10 @@ * position classes to given modal * * @param {HTMLElement} modal - * @param {Array} allowed_layouts - * @param {Array} allowed_positions - * @param {String} layout - * @param {Array} position + * @param {string[]} allowed_layouts + * @param {string[]} allowed_positions + * @param {string} layout + * @param {string[]} position */ function _setLayout(modal, allowed_layouts, allowed_positions, allowed_transitions, layout, position, transition){ position = position && position.split(" ") || []; @@ -1021,7 +1023,7 @@ // Check if specified layout is valid if(_inArray(allowed_layouts, layout) > -1){ - // Add layout classe + // Add layout classes _addClass(modal, layout); // Add position class (if specified) @@ -1063,8 +1065,8 @@ /** * Returns true if cookie category is accepted by the user - * @param {String} cookie_category - * @returns {Boolean} + * @param {string} cookie_category + * @returns {boolean} */ _cookieconsent.allowedCategory = function(cookie_category){ return _inArray( @@ -1074,7 +1076,7 @@ } /** - * Check if cookieconsent is alredy attached to dom + * Check if cookieconsent is already attached to dom * If not, create one, configure it and attach it to the body */ _cookieconsent.run = function(conf_params){ @@ -1117,13 +1119,13 @@ } } }else{ - _log("CookieConsent [NOTICE]: cookie consent alredy attached to body!"); + _log("CookieConsent [NOTICE]: cookie consent already attached to body!"); } } /** * Show settings modal (with optional delay) - * @param {Number} delay + * @param {number} delay */ _cookieconsent.showSettings = function(delay){ setTimeout(function() { @@ -1157,7 +1159,7 @@ } /** - * This function handles the loading/activation logic of the alredy + * This function handles the loading/activation logic of the already * existing scripts based on the current accepted cookie categories */ var _manageExistingScripts = function(){ @@ -1166,15 +1168,15 @@ // get all the scripts with "cookie-category" attribute var scripts = document.querySelectorAll('script[' + _config.script_selector + ']'); - var sequental_enabled = _config.page_scripts_order; + var sequential_enabled = _config.page_scripts_order; var accepted_categories = JSON.parse(_saved_cookie_content).level || []; - _log("CookieConsent [SCRIPT_MANAGER]: sequential loading:", sequental_enabled); + _log("CookieConsent [SCRIPT_MANAGER]: sequential loading:", sequential_enabled); /** - * Load scripts (sequentally), using a recursive function + * Load scripts (sequentially), using a recursive function * which loops through the scripts array - * @param {Array} scripts scripts to load - * @param {Number} index current script to load + * @param {Element[]} scripts scripts to load + * @param {number} index current script to load */ var _loadScripts = function(scripts, index){ if(index < scripts.length){ @@ -1214,7 +1216,7 @@ // if script has "src" attribute // try loading it sequentially if(src){ - if(sequental_enabled){ + if(sequential_enabled){ // load script sequentially => the next script will not be loaded // until the current's script onload event triggers if(fresh_script.readyState) { // only required for IE <9 @@ -1255,17 +1257,22 @@ _loadScripts(scripts, 0); } + /** + * Function which will run after script load + * @callback scriptLoaded + */ + /** * Dynamically load script (append to head) - * @param {String} src - * @param {Function} callback - * @param {Array} attrs + * @param {string} src + * @param {scriptLoaded} callback + * @param {string[]} attrs */ _cookieconsent.loadScript = function(src, callback, attrs){ var function_defined = typeof callback === 'function'; - // Load script only if not alredy loaded + // Load script only if not already loaded if(!document.querySelector('script[src="' + src + '"]')){ var script = _createNode('script'); @@ -1304,7 +1311,7 @@ /** * Show cookie consent modal (with delay parameter) - * @param {Number} delay + * @param {number} delay */ _cookieconsent.show = function(delay){ if(consent_modal_exists){ @@ -1393,8 +1400,8 @@ /** * Set cookie, by specifying name and value - * @param {String} name - * @param {String} value + * @param {string} name + * @param {string} value */ var _setCookie = function(name, value) { @@ -1423,8 +1430,10 @@ * Get cookie value by name, * returns the cookie value if found (or an array * of cookies if filter provided), otherwise empty string: "" - * @param {String} name - * @returns {String} + * @param {string} name + * @param {string} filter ('one' or 'aLL') + * @param {boolean} get_value + * @returns {string|string[]} */ var _getCookie = function(name, filter, get_value) { var found; @@ -1444,9 +1453,9 @@ /** * Delete cookie by name & path - * @param {Array} cookies - * @param {String} custom_path - * @param {Array} domains ['www.domain.com', '.www.domain.com', 'domain.com', '.domain.com'] + * @param {string[]} cookies + * @param {string} custom_path + * @param {string[]} domains ['www.domain.com', '.www.domain.com', 'domain.com', '.domain.com'] */ var _eraseCookies = function(cookies, custom_path, domains) { var path = custom_path ? custom_path : '/'; @@ -1461,20 +1470,25 @@ } /** - * Return true if cookie was found and has valid value (not empty string) - * @param {String} cookie_name - * @returns {Boolean} + * Returns true if cookie was found and has valid value (not empty string) + * @param {string} cookie_name + * @returns {boolean} */ _cookieconsent.validCookie = function(cookie_name){ return _getCookie(cookie_name, 'one', true) != ""; } + /** + * Function to run when event is fired + * @callback eventFired + */ + /** * Add event listener to dom object (cross browser function) - * @param {Object} elem - * @param {String} event //event type - * @param {Object } fn - * @param {Boolean} passive + * @param {Element} elem + * @param {string} event //event type + * @param {eventFired} fn + * @param {boolean} passive */ var _addEvent = function(elem, event, fn, passive) { var passive = passive || false; @@ -1505,7 +1519,7 @@ /** * Append class to the specified dom element * @param {HTMLElement} elem - * @param {String} classname + * @param {string} classname */ var _addClass = function (elem, classname){ if(elem.classList) @@ -1519,7 +1533,7 @@ /** * Remove specified class from dom element * @param {HTMLElement} elem - * @param {String} classname + * @param {string} classname */ var _removeClass = function (el, className) { el.classList ? el.classList.remove(className) : el.className = el.className.replace(new RegExp('(\\s|^)' + className + '(\\s|$)'), ' '); @@ -1528,7 +1542,7 @@ /** * Check if html element has classname * @param {HTMLElement} el - * @param {String} className + * @param {string} className */ var _hasClass = function(el, className) { if (el.classList) { From e17534091a2f6ca549495bf950030b2c6ab03b2a Mon Sep 17 00:00:00 2001 From: Orest Bida Date: Thu, 26 Aug 2021 04:29:44 +0200 Subject: [PATCH 03/17] add `.eraseCookies()` and `.accept()` API --- src/cookieconsent.js | 263 ++++++++++++++++++++++++++++--------------- 1 file changed, 175 insertions(+), 88 deletions(-) diff --git a/src/cookieconsent.js b/src/cookieconsent.js index 17f28109..794e9a9e 100644 --- a/src/cookieconsent.js +++ b/src/cookieconsent.js @@ -7,12 +7,14 @@ (function(){ 'use strict'; /** - * @param {HTMLElement} root element where the cookieconsent will be appended (default :=> document.body) - * @returns {Object} + * @param {HTMLElement} [root] - [optional] element where the cookieconsent will be appended + * @returns {Object} cookieconsent object with API */ var CookieConsent = function(root){ - // CHANGE THIS FLAG FALSE TO DISABLE console.log() + /** + * CHANGE THIS FLAG FALSE TO DISABLE console.log() + */ var ENABLE_LOGS = true; var _config = { @@ -23,11 +25,13 @@ cookie_domain: location.hostname, // default: current domain cookie_path: "/", cookie_same_site: "Lax", + consent_revision: 1, + autoclear_cookies: true, script_selector: "data-cookiecategory" }; /** - * Object which holds the main methods (.show, .run, ...) + * Object which holds the main methods/API (.show, .run, ...) */ var _cookieconsent = {}; @@ -41,6 +45,7 @@ var settings_modal_visible = false; var clicked_inside_modal = false; var current_modal_focusable; + var all_table_headers, all_blocks, onAccept, onChange; /** * Save reference to the last focused element on the page @@ -58,10 +63,22 @@ var settings_modal_focusable = []; /** - * Array of booleans used to keep track of enabled/disabled preferences + * Keep track of enabled/disabled categories * @type {boolean[]} */ var toggle_states = []; + + /** + * Stores all available categories + * @type {string[]} + */ + var toggle_categories = []; + + /** + * Keep track of readonly toggles + * @type {boolean[]} + */ + var toggle_readonly = []; /** * Pointers to main dom elements (to avoid retrieving them later using document.getElementById) @@ -102,6 +119,22 @@ _config.cookie_name = conf_params['cookie_name']; } + if(typeof conf_params['onAccept'] === "function"){ + onAccept = conf_params['onAccept']; + } + + if(typeof conf_params['onChange'] === "function"){ + onChange = conf_params['onChange']; + } + + if(typeof conf_params['consent_revision'] === "number"){ + _config.consent_revision = conf_params['consent_revision']; + } + + if(conf_params['autoclear_cookies'] === true){ + _config.autoclear_cookies = true; + } + _config.page_scripts = conf_params['page_scripts'] === true; _config.page_scripts_order = conf_params['page_scripts_order'] !== false; @@ -217,9 +250,12 @@ } } + /** * Generate cookie consent html based on config settings - */ + * @param {boolean} never_accepted - used to know whether to create both modals or not + * @param {Object} conf_params - user configuration parameters + */ var _createCookieConsentHTML = function(never_accepted, conf_params){ // Create main container which holds both consent modal & settings modal @@ -284,22 +320,22 @@ consent_primary_btn[innerText] = conf_params.languages[lang]['consent_modal']['primary_btn']['text']; consent_secondary_btn[innerText] = conf_params.languages[lang]['consent_modal']['secondary_btn']['text']; - var accept_type = -1; // accept current selection + var accept_type; // accept current selection if(conf_params.languages[lang]['consent_modal']['primary_btn']['role'] == 'accept_all'){ - accept_type = 1; // accept all + accept_type = 'all'; // accept all } _addEvent(consent_primary_btn, "click", function(){ _cookieconsent.hide(); _log("CookieConsent [ACCEPT]: cookie_consent was accepted!"); - _saveCookiePreferences(conf_params, accept_type); + _cookieconsent.accept(accept_type); }); if(conf_params.languages[lang]['consent_modal']['secondary_btn']['role'] == 'accept_necessary'){ _addEvent(consent_secondary_btn, 'click', function(){ _cookieconsent.hide(); - _saveCookiePreferences(conf_params, 0); // 0 => accept necessary only + _cookieconsent.accept([]); // accept necessary only }); }else{ _addEvent(consent_secondary_btn, 'click', function(){ @@ -374,7 +410,7 @@ _cookieconsent.hideSettings(0); }); - var all_blocks = conf_params.languages[_config.current_lang]['settings_modal']['blocks']; + all_blocks = conf_params.languages[_config.current_lang]['settings_modal']['blocks']; var n_blocks = all_blocks.length; // Set settings modal title @@ -450,8 +486,13 @@ } }else if(all_blocks[i]['toggle']['enabled']){ block_switch.checked = true; + toggle_states.push(true); + }else{ + toggle_states.push(false); } + toggle_categories.push(cookie_category); + /** * Set toggle as readonly if true (disable checkbox) */ @@ -459,6 +500,9 @@ block_switch.disabled = true; block_switch.setAttribute('aria-readonly', 'true'); _addClass(block_switch_span, 'c-ro'); + toggle_readonly.push(true); + }else{ + toggle_readonly.push(false); } _addClass(block_table_container, 'b-acc'); @@ -512,7 +556,7 @@ // if cookie table found, generate table for this block if(!remove_cookie_tables && typeof all_blocks[i]['cookie_table'] !== 'undefined'){ var tr_tmp_fragment = document.createDocumentFragment(); - var all_table_headers = conf_params.languages[_config.current_lang]['settings_modal']['cookie_table_headers']; + all_table_headers = conf_params.languages[_config.current_lang]['settings_modal']['cookie_table_headers']; /** * Use custom table headers @@ -602,13 +646,13 @@ _addEvent(settings_save_btn, 'click', function(){ _cookieconsent.hideSettings(); _cookieconsent.hide(); - _saveCookiePreferences(conf_params, -1); + _cookieconsent.accept(); }); _addEvent(settings_accept_all_btn, 'click', function(){ _cookieconsent.hideSettings(); _cookieconsent.hide(); - _saveCookiePreferences(conf_params, 1); + _cookieconsent.accept('all'); }); settings_header.appendChild(settings_title); @@ -631,76 +675,42 @@ } /** - * Save cookie preferences - * accept_type = 0: accept necessary only - * accept_type = 1: accept all - * accept_type = -1: accept selection + * Set toggles/checkboxes based on accepted categories and save cookie + * @param {string[]} accepted_categories - Array of categories to accept */ - var _saveCookiePreferences = function(conf_params, accept_type){ + var _saveCookiePreferences = function(accepted_categories){ // Retrieve all toggle/checkbox values var category_toggles = document.querySelectorAll('.c-tgl') || []; - var c_cookie_level = '', changedSettings = [], must_reload = false; - + var changedSettings = [], must_reload = false; + // If there are opt in/out toggles ... if(category_toggles.length > 0){ - switch(accept_type){ - case -1: - //accept current selection - for(var i=0; i delete all cookies which are unused (based on selected preferences) */ - if(conf_params['autoclear_cookies'] && cookie_consent_accepted && changedSettings.length > 0){ - - // Get array of all blocks defined inside settings - var all_blocks = conf_params.languages[_config.current_lang]['settings_modal']['blocks']; + if(_config.autoclear_cookies && cookie_consent_accepted && changedSettings.length > 0){ // Get number of blocks var len = all_blocks.length; @@ -738,7 +748,7 @@ var curr_cookie_table = curr_block['cookie_table']; // Get first property name - var ckey = _getKeys(conf_params.languages[_config.current_lang]['settings_modal']['cookie_table_headers'][0])[0]; + var ckey = _getKeys(all_table_headers[0])[0]; // Get number of cookies defined in cookie_table var clen = curr_cookie_table.length; @@ -785,7 +795,10 @@ } } - _saved_cookie_content = '{"level": ['+c_cookie_level+']}'; + _saved_cookie_content = JSON.stringify({ + "level" : accepted_categories, + "revision": _config.consent_revision + }); // save cookie with preferences 'level' (only if never accepted or settings were updated) if(!cookie_consent_accepted || changedSettings.length > 0) @@ -793,14 +806,14 @@ _manageExistingScripts(); - if(typeof conf_params['onAccept'] === "function" && !cookie_consent_accepted){ + if(typeof onAccept === "function" && !cookie_consent_accepted){ cookie_consent_accepted = true; - return conf_params['onAccept'](JSON.parse(_saved_cookie_content)); + return onAccept(JSON.parse(_saved_cookie_content)); } // fire onChange only if settings were changed - if(typeof conf_params['onChange'] === "function" && changedSettings.length > 0){ - conf_params['onChange'](JSON.parse(_saved_cookie_content)); + if(typeof onChange === "function" && changedSettings.length > 0){ + onChange(JSON.parse(_saved_cookie_content)); } /** @@ -1086,9 +1099,12 @@ // Retrieve cookie value (if set) _saved_cookie_content = _getCookie(_config.cookie_name, 'one', true); + + // Compare current revision with the one retrieved from cookie + var valid_revision = (_saved_cookie_content && JSON.parse(_saved_cookie_content || "{}")['revision'] === _config.consent_revision) === true; - // If cookie is empty => create consent modal - consent_modal_exists = _saved_cookie_content == ''; + // If invalid revision or cookie is empty => create consent modal + consent_modal_exists = (!valid_revision || _saved_cookie_content === ''); // Generate cookie-settings dom (& consent modal) _createCookieConsentHTML(!consent_modal_exists, conf_params); @@ -1098,7 +1114,7 @@ _guiManager(conf_params['gui_options']); _addCookieSettingsButtonListener(); - if(!_saved_cookie_content && _config.autorun){ + if(_config.autorun && (!_saved_cookie_content || !valid_revision)){ _cookieconsent.show(conf_params['delay'] || 0); } @@ -1373,11 +1389,82 @@ _log("CookieConsent [SETTINGS]: hide settings_modal"); } + /** + * Accept cookieconsent function API + * @param {string[]|string} _categories - Categories to accept + * @param {string[]} [_exclusions] - Excluded categories [optional] + */ + _cookieconsent.accept = function(_categories, _exclusions){ + var categories = _categories || undefined; + var exclusions = _exclusions || []; + var to_accept = []; + + /** + * Get all accepted categories + * @returns {string[]} + */ + var _getCurrentPreferences = function(){ + var toggles = document.querySelectorAll('.c-tgl') || []; + var states = []; + + for(var i=0; i= 1){ + for(var i=0; i Date: Thu, 26 Aug 2021 15:54:04 +0200 Subject: [PATCH 04/17] add support for consent revision (#43) --- src/cookieconsent.js | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/cookieconsent.js b/src/cookieconsent.js index 794e9a9e..3ceac695 100644 --- a/src/cookieconsent.js +++ b/src/cookieconsent.js @@ -25,8 +25,8 @@ cookie_domain: location.hostname, // default: current domain cookie_path: "/", cookie_same_site: "Lax", - consent_revision: 1, autoclear_cookies: true, + revision: 0, script_selector: "data-cookiecategory" }; @@ -46,6 +46,7 @@ var clicked_inside_modal = false; var current_modal_focusable; var all_table_headers, all_blocks, onAccept, onChange; + var valid_revision, revision_enabled; /** * Save reference to the last focused element on the page @@ -127,8 +128,9 @@ onChange = conf_params['onChange']; } - if(typeof conf_params['consent_revision'] === "number"){ - _config.consent_revision = conf_params['consent_revision']; + if(typeof conf_params['revision'] === "number"){ + _config.revision = conf_params['revision']; + revision_enabled = true; } if(conf_params['autoclear_cookies'] === true){ @@ -315,7 +317,18 @@ // Use insertAdjacentHTML instead of innerHTML consent_title.insertAdjacentHTML('beforeend', conf_params.languages[lang]['consent_modal']['title']); - consent_text.insertAdjacentHTML('beforeend', conf_params.languages[lang]['consent_modal']['description']); + + var description = conf_params.languages[lang]['consent_modal']['description']; + + if(revision_enabled){ + if(!valid_revision){ + description = description.replace("{{revision_message}}", conf_params.languages[lang]['consent_modal']['revision_message'] || ""); + }else{ + description = description.replace("{{revision_message}}", ""); + } + } + + consent_text.insertAdjacentHTML('beforeend', description); consent_primary_btn[innerText] = conf_params.languages[lang]['consent_modal']['primary_btn']['text']; consent_secondary_btn[innerText] = conf_params.languages[lang]['consent_modal']['secondary_btn']['text']; @@ -550,7 +563,6 @@ block_section.appendChild(block_title_container); block_table_container.appendChild(block_desc); - // [NEW] var remove_cookie_tables = conf_params['remove_cookie_tables'] === true; // if cookie table found, generate table for this block @@ -687,19 +699,14 @@ // If there are opt in/out toggles ... if(category_toggles.length > 0){ for(var i=0; i create consent modal consent_modal_exists = (!valid_revision || _saved_cookie_content === ''); @@ -1518,7 +1529,7 @@ * returns the cookie value if found (or an array * of cookies if filter provided), otherwise empty string: "" * @param {string} name - * @param {string} filter - ('one' or 'aLL') + * @param {string} filter - 'one' or 'all' * @param {boolean} get_value - set to true to obtain its value * @returns {string|string[]} */ From 18e810b3e38c0e34eac2e5ca8146a44d13319a8f Mon Sep 17 00:00:00 2001 From: Orest Bida Date: Thu, 26 Aug 2021 20:00:15 +0200 Subject: [PATCH 05/17] add optional reject_all button inside settings modal --- src/cookieconsent.js | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/cookieconsent.js b/src/cookieconsent.js index 3ceac695..aa956e16 100644 --- a/src/cookieconsent.js +++ b/src/cookieconsent.js @@ -642,7 +642,7 @@ var settings_buttons = _createNode('div'); var settings_save_btn = _createNode('button'); var settings_accept_all_btn = _createNode('button'); - + settings_buttons.id = 's-bns'; settings_save_btn.id = 's-sv-bn'; settings_accept_all_btn.id = 's-all-bn'; @@ -650,7 +650,29 @@ settings_accept_all_btn.className ='c-bn'; settings_save_btn.insertAdjacentHTML('beforeend', conf_params.languages[_config.current_lang]['settings_modal']['save_settings_btn']); settings_accept_all_btn.insertAdjacentHTML('beforeend', conf_params.languages[_config.current_lang]['settings_modal']['accept_all_btn']); + settings_buttons.appendChild(settings_accept_all_btn); + + var reject_all_btn_text = conf_params.languages[_config.current_lang]['settings_modal']['reject_all_btn']; + + // Add third [optional] reject all button if provided + if(reject_all_btn_text){ + + var reject_all_btn = _createNode('button'); + reject_all_btn.id = 's-rall-bn'; + reject_all_btn.className = 'c-bn'; + reject_all_btn.insertAdjacentHTML('beforeend', reject_all_btn_text); + + _addEvent(reject_all_btn, 'click', function(){ + _cookieconsent.hideSettings(); + _cookieconsent.hide(); + _cookieconsent.accept([]); + }); + + settings_inner.className = "bns-t"; + settings_buttons.appendChild(reject_all_btn); + } + settings_buttons.appendChild(settings_save_btn); // Add save preferences button onClick event @@ -1405,7 +1427,7 @@ * @param {string[]|string} _categories - Categories to accept * @param {string[]} [_exclusions] - Excluded categories [optional] */ - _cookieconsent.accept = function(_categories, _exclusions){ + _cookieconsent.accept = function(_categories, _exclusions){ var categories = _categories || undefined; var exclusions = _exclusions || []; var to_accept = []; From bbf50572a3f669740c6512458060cebf28c1ae1f Mon Sep 17 00:00:00 2001 From: Orest Bida Date: Thu, 26 Aug 2021 22:17:00 +0200 Subject: [PATCH 06/17] minor ui tweaks --- src/cookieconsent.css | 88 +++++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 36 deletions(-) diff --git a/src/cookieconsent.css b/src/cookieconsent.css index b1cb0bc4..3f53ae01 100644 --- a/src/cookieconsent.css +++ b/src/cookieconsent.css @@ -209,13 +209,13 @@ #c-ttl{ margin: 0 0 0.6em 0; - font-size: 1.3em; + font-size: 1.1em; } #c-txt{ margin-bottom: 1.625em; font-size: 0.9em; - line-height: 1.45em; + line-height: 1.5em; } .cc_div .c-bn{ @@ -223,10 +223,10 @@ color: var(--cc-btn-secondary-text); background: #e5ebef; background: var(--cc-btn-secondary-bg); - padding: 1em 1.6em; + padding: 1em 1.7em; display: inline-block; cursor: pointer; - font-size: 0.85em; + font-size: 0.82em; -moz-user-select: none; -khtml-user-select: none; -webkit-user-select: none; @@ -246,6 +246,11 @@ float: right; } +#s-cnt #s-rall-bn{ + float: none; + margin-left: 1em; +} + #cm .c_link:hover, #cm .c_link:active, #s-cnt button + button:hover, @@ -282,10 +287,6 @@ CookieConsent settings modal margin-top: 0; } -#s-bl .b-tl{ - font-size: 1.1em; -} - #s-bl .b-bn{ margin-top: 0; } @@ -298,11 +299,11 @@ CookieConsent settings modal #s-cnt .b-bn .b-tl{ display: block; font-family: inherit; - font-size: 1em; + font-size: .95em; width: 100%; cursor: pointer; position: relative; - padding: 1.4em 6.4em 1.4em 2.7em; + padding: 1.3em 6.4em 1.3em 2.7em; background: none; transition: background-color .25s ease; } @@ -393,7 +394,7 @@ CookieConsent settings modal #s-cnt .p{ font-size: 0.9em; - line-height: 1.3em; + line-height: 1.5em; margin-top: 1em; } @@ -421,12 +422,12 @@ CookieConsent settings modal #s-inr{ height: 100%; position: relative; - max-width: 47em; + max-width: 45em; margin: 0 auto; transform: scale(.96); opacity: 0; padding-top: 5.125em; - padding-bottom: 4.9375em; + padding-bottom: 4.75em; position: relative; height: 100%; overflow: hidden; @@ -459,7 +460,7 @@ CookieConsent settings modal padding: 1em 2.5em; border-top: 1px solid #f1f3f5; border-color: var(--cc-section-border); - height: 4.9375em; + height: 4.75em; } .cc_div .cc-link{ @@ -505,7 +506,8 @@ CookieConsent settings modal top: 0; width: 100%; display: table; - padding: 1.2em 2.5em; + padding: 0 2.5em; + height: 5.125em; vertical-align: middle; z-index: 2; border-bottom: 1px solid #f1f3f5; @@ -522,7 +524,7 @@ CookieConsent settings modal padding: 0; width: 1.7em; height: 1.7em; - font-size: 1.6em; + font-size: 1.55em; margin: 0; font-weight: initial; position: relative; @@ -644,7 +646,7 @@ CookieConsent settings modal content: ""; position: absolute; left: 0.22em; - top: 0.2em; + top: 50%; width: 1.2em; height: 1.2em; border: none; @@ -653,12 +655,13 @@ CookieConsent settings modal background: var(--cc-toggle-knob-bg); box-shadow: 0 1px 2px rgba(24, 32, 35, .36); transition: transform .25s ease; + transform: translateY(-50%); border-radius: 100%; } /* Show the checkmark when checked */ .cc_div .c-tgl:checked ~ .c-tg:after{ - transform: translateX(1.95em); + transform: translateY(-50%) translateX(1.95em); } #s-bl table, @@ -785,13 +788,13 @@ html.force--consent body{ content: ''; margin-right: 15px; position: absolute; - transform: translateY(-.2em) rotate(45deg); + transform: translateY(-50%) rotate(45deg); left: 1.2em; - top: 1.85em; + top: 50%; } .cc_div .act .b-bn .b-tl::before{ - transform: translateY(.05em) rotate(225deg); + transform: translateY(-20%) rotate(225deg); } .cc_div .on-i::before{ @@ -813,8 +816,8 @@ html.force--consent body{ content: ''; position: absolute; left: .82em; - top: .55em; - height: 17px; + top: .58em; + height: .6em; width: 1.5px; background: #444d53; background: var(--cc-btn-secondary-text); @@ -898,10 +901,6 @@ html.force--consent body{ padding-right: 2.4em; } -.cc_div .cloud #c-ttl{ - font-size: 1.1em; -} - .cc_div .cloud #c-txt{ margin-bottom: 0; font-size: 0.85em; @@ -916,7 +915,6 @@ html.force--consent body{ #cm.cloud .c-bn{ margin: .625em 0 0 0; width: 100%; - font-size: .8em; } #cm.cloud .c-bn:first-child{ @@ -1070,7 +1068,7 @@ html.force--consent body{ width: 100%; max-width: 100%; margin: 0; - padding: 1.875em; + padding: 1.6em!important; right: 0; left: 0; bottom: 0; @@ -1093,10 +1091,6 @@ html.force--consent body{ bottom: 0; top: unset; } - - .cc_div .cloud #c-ttl{ - font-size: 1.3em; - } .cc_div .cloud #c-txt{ font-size: .9em; @@ -1128,7 +1122,7 @@ html.force--consent body{ } .cc_div .b-tg{ - font-size: 1.25em; + font-size: 1.1em; right: .9em; } @@ -1145,7 +1139,7 @@ html.force--consent body{ #s-hdr, .cc_div .bar #s-hdr{ - padding: 1.2em 1.3em; + padding: 0 1.3em; } #s-bns, @@ -1159,6 +1153,24 @@ html.force--consent body{ width: 100%; } + #s-inr.bns-t{ + padding-bottom: 10.5em; + } + + .bns-t #s-bns{ + height: 10.5em; + } + + .cc_div .bns-t .c-bn{ + font-size: 0.83em; + padding: .9em 1.6em; + } + + #s-cnt .b-bn .b-tl{ + padding-top: 1.2em; + padding-bottom: 1.2em; + } + /* Force table to not be like tables anymore */ #s-bl table, #s-bl thead, @@ -1207,6 +1219,10 @@ html.force--consent body{ margin-right: 0; } + #s-cnt #s-rall-bn{ + margin-left: 0; + } + #c-bns button + button, #s-cnt button + button{ margin-top: 0.625em; @@ -1295,7 +1311,7 @@ html.force--consent body{ } .cc_div.ie #s-cnt .b-bn .b-tl{ - padding: 1.4em 6.4em 1.4em 1.4em + padding: 1.3em 6.4em 1.3em 1.4em } .cc_div.ie .bar #s-bl td:before{ From 561e56ef38881b5c873b3fe0b770726b0f8178f6 Mon Sep 17 00:00:00 2001 From: Orest Bida Date: Fri, 27 Aug 2021 14:34:58 +0200 Subject: [PATCH 07/17] delay low priority operations during transition execution time-frame --- src/cookieconsent.js | 71 +++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/src/cookieconsent.js b/src/cookieconsent.js index aa956e16..9f122a78 100644 --- a/src/cookieconsent.js +++ b/src/cookieconsent.js @@ -511,7 +511,6 @@ */ if(all_blocks[i]['toggle']['readonly']){ block_switch.disabled = true; - block_switch.setAttribute('aria-readonly', 'true'); _addClass(block_switch_span, 'c-ro'); toggle_readonly.push(true); }else{ @@ -720,17 +719,18 @@ // If there are opt in/out toggles ... if(category_toggles.length > 0){ + for(var i=0; i 0 ? delay : 0); @@ -1372,8 +1372,12 @@ */ consent_modal.setAttribute('aria-hidden', 'false'); consent_modal_visible = true; - last_elem_before_modal = document.activeElement; - current_modal_focusable = consent_modal_focusable; + + + setTimeout(function(){ + last_elem_before_modal = document.activeElement; + current_modal_focusable = consent_modal_focusable; + }, 200); _log("CookieConsent [MODAL]: show consent_modal"); }, delay > 0 ? delay : 0); @@ -1389,9 +1393,12 @@ consent_modal.setAttribute('aria-hidden', 'true'); consent_modal_visible = false; - //restore focus to the last page element which had focus before modal opening - last_elem_before_modal.focus(); - current_modal_focusable = null; + setTimeout(function(){ + //restore focus to the last page element which had focus before modal opening + last_elem_before_modal.focus(); + current_modal_focusable = null; + }, 200); + _log("CookieConsent [MODAL]: hide"); } } @@ -1404,21 +1411,25 @@ settings_modal_visible = false; settings_container.setAttribute('aria-hidden', 'true'); - /** - * If consent modal is visible, focus him (instead of page document) - */ - if(consent_modal_visible){ - last_consent_modal_btn_focus && last_consent_modal_btn_focus.focus(); - current_modal_focusable = consent_modal_focusable; - }else{ + + setTimeout(function(){ /** - * Restore focus to last page element which had focus before modal opening + * If consent modal is visible, focus him (instead of page document) */ - last_elem_before_modal.focus(); - current_modal_focusable = null; - } + if(consent_modal_visible){ + last_consent_modal_btn_focus && last_consent_modal_btn_focus.focus(); + current_modal_focusable = consent_modal_focusable; + }else{ + /** + * Restore focus to last page element which had focus before modal opening + */ + last_elem_before_modal.focus(); + current_modal_focusable = null; + } - clicked_inside_modal = false; + clicked_inside_modal = false; + }, 200); + _log("CookieConsent [SETTINGS]: hide settings_modal"); } @@ -1489,8 +1500,6 @@ } _saveCookiePreferences(to_accept); - - this.hide(); } /** From c8c521a3d443b81d11891208fffa8d1a8576e229 Mon Sep 17 00:00:00 2001 From: Orest Bida Date: Fri, 27 Aug 2021 14:51:33 +0200 Subject: [PATCH 08/17] use better system fonts --- src/cookieconsent.css | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/cookieconsent.css b/src/cookieconsent.css index 3f53ae01..6e59f364 100644 --- a/src/cookieconsent.css +++ b/src/cookieconsent.css @@ -75,7 +75,10 @@ .cc_div { font-size: 16px; font-weight: 400; - font-family: -apple-system, sans-serif; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-rendering: optimizeLegibility; color: #2d4156; color: var(--cc-text); } @@ -85,7 +88,7 @@ #s-ttl, #c-ttl, #s-bl td:before{ - font-weight: bold; + font-weight: 600; } #cm, @@ -105,11 +108,12 @@ } .cc_div a{ - text-decoration: underline; + border-bottom: 1px solid; } .cc_div a:hover{ text-decoration: none; + border-color: transparent; } /* Make elements "animatable" */ @@ -472,7 +476,7 @@ CookieConsent settings modal padding-bottom: 0; text-decoration: none; cursor: pointer; - font-weight: bold; + font-weight: 600; } .cc_div .cc-link:hover, @@ -607,6 +611,8 @@ CookieConsent settings modal position: absolute; cursor: pointer; display: block; + top: 0; + left: 0; } /* Create a custom checkbox */ @@ -1247,7 +1253,7 @@ html.force--consent body{ .cc_div .cloud #c-inr-i{ display: block; width: auto; - min-width: auto; + min-width: unset; } .cc_div .cloud #c-txt{ From af43cdef4b0b2aa7acad4cdae15f76413d7c180f Mon Sep 17 00:00:00 2001 From: Orest Bida Date: Fri, 27 Aug 2021 17:52:39 +0200 Subject: [PATCH 09/17] add changed preferences as parameter to the onChange function --- src/cookieconsent.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cookieconsent.js b/src/cookieconsent.js index 9f122a78..3e092ad5 100644 --- a/src/cookieconsent.js +++ b/src/cookieconsent.js @@ -842,7 +842,7 @@ // fire onChange only if settings were changed if(typeof onChange === "function" && changedSettings.length > 0){ - onChange(JSON.parse(_saved_cookie_content)); + onChange(JSON.parse(_saved_cookie_content), changedSettings); } /** From 156b5008449dd2ea00d7073262b2954c9c1c25e4 Mon Sep 17 00:00:00 2001 From: Orest Bida Date: Fri, 27 Aug 2021 17:53:55 +0200 Subject: [PATCH 10/17] minor ui tweaks --- src/cookieconsent.css | 56 +++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/src/cookieconsent.css b/src/cookieconsent.css index 6e59f364..d13ed1a8 100644 --- a/src/cookieconsent.css +++ b/src/cookieconsent.css @@ -13,6 +13,7 @@ --cc-toggle-bg-readonly: #d5dee2; --cc-toggle-knob-bg: #fff; --cc-toggle-knob-icon-color: #ecf2fa; + --cc-block-text: var(--cc-text); --cc-cookie-category-block-bg: #f0f4f7; --cc-cookie-category-block-bg-hover: #e9eff4; --cc-section-border: #f1f3f5; @@ -37,6 +38,7 @@ --cc-toggle-bg-readonly: #454c54; --cc-toggle-knob-bg: var(--cc-cookie-category-block-bg); --cc-toggle-knob-icon-color: var(--cc-bg); + --cc-block-text: #b3bfc5; --cc-cookie-category-block-bg: #23272a; --cc-cookie-category-block-bg-hover: #2b3035; --cc-section-border: #292d31; @@ -96,7 +98,7 @@ .cc_div .c-bl, .cc_div .b-tl, #s-bl .act .b-acc{ - border-radius: .25em; + border-radius: .35em; } .cc_div input, @@ -122,7 +124,7 @@ .c--anim #s-inr, #cs-ov, #cm-ov{ - transition: visibility .25s ease, opacity .25s ease, transform .25s ease!important; + transition: visibility .25s linear, opacity .25s ease, transform .25s ease!important; } .c--anim .c-bn{ @@ -194,7 +196,7 @@ #cm{ font-family: inherit; - padding: 1.2em 2.2em 1.825em 2.2em; + padding: 1.05em 2.1em 1.5em 2.1em; position: fixed; z-index: 1; background: #fff; @@ -212,12 +214,12 @@ } #c-ttl{ - margin: 0 0 0.6em 0; - font-size: 1.1em; + margin: 0 0 0.7em 0; + font-size: 1.05em; } #c-txt{ - margin-bottom: 1.625em; + margin-bottom: 1.4em; font-size: 0.9em; line-height: 1.5em; } @@ -400,6 +402,8 @@ CookieConsent settings modal font-size: 0.9em; line-height: 1.5em; margin-top: 1em; + color: #2d4156; + color: var(--cc-block-text); } .cc_div .c-tgl:disabled{ @@ -528,7 +532,7 @@ CookieConsent settings modal padding: 0; width: 1.7em; height: 1.7em; - font-size: 1.55em; + font-size: 1.515em; margin: 0; font-weight: initial; position: relative; @@ -651,23 +655,22 @@ CookieConsent settings modal .cc_div .b-tg .c-tg:after { content: ""; position: absolute; - left: 0.22em; - top: 50%; - width: 1.2em; - height: 1.2em; + left: 0.24em; + top: 0.25em; + width: 1.1em; + height: 1.1em; border: none; box-sizing: content-box; background: #fff; background: var(--cc-toggle-knob-bg); box-shadow: 0 1px 2px rgba(24, 32, 35, .36); transition: transform .25s ease; - transform: translateY(-50%); border-radius: 100%; } /* Show the checkmark when checked */ .cc_div .c-tgl:checked ~ .c-tg:after{ - transform: translateY(-50%) translateX(1.95em); + transform: translateX(1.95em); } #s-bl table, @@ -753,7 +756,7 @@ CookieConsent settings modal width: 100%; width: 100vw; visibility: hidden; - transition: visibility .25s ease; + transition: visibility .25s linear; } .force--consent.show--consent .c--anim .cc_div, @@ -971,8 +974,8 @@ html.force--consent body{ .cc_div .bar #s-hdr, .cc_div .bar #s-bl, .cc_div .bar #s-bns { - padding-left: 2em; - padding-right: 2em; + padding-left: 1.8em; + padding-right: 1.8em; } .cc_div .bar #cs{ @@ -1063,8 +1066,6 @@ html.force--consent body{ } /* end positions */ - - @media screen and (max-width: 688px) { #cm, @@ -1106,6 +1107,11 @@ html.force--consent body{ font-size: .85em; } + #s-bns, + .cc_div .bar #s-bns{ + padding: 1em 1.3em; + } + .cc_div .bar #s-inr{ max-width: 100%; width: 100%; @@ -1134,10 +1140,14 @@ html.force--consent body{ #s-inr{ margin: 0; - padding-bottom: 8.1em; + padding-bottom: 7.9em; border-radius: unset; } + #s-bns{ + height: 7.9em; + } + #s-bl, .cc_div .bar #s-bl{ padding: 1.3em; @@ -1148,12 +1158,6 @@ html.force--consent body{ padding: 0 1.3em; } - #s-bns, - .cc_div .bar #s-bns{ - height: 8.1em; - padding: 1em 1.3em; - } - /** dynamic table layout **/ #s-bl table { width: 100%; @@ -1341,4 +1345,4 @@ html.force--consent body{ filter: alpha(opacity=80); } -/** END IE FIXES **/ +/** END IE FIXES **/ \ No newline at end of file From cfe8a3f1c6a7602c9ec21a4885fb811d05d94b0f Mon Sep 17 00:00:00 2001 From: Orest Bida Date: Fri, 27 Aug 2021 18:40:36 +0200 Subject: [PATCH 11/17] add documentation for eraseCookies() (#58) and ccept() (#47) API calls --- Readme.md | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/Readme.md b/Readme.md index 30a1a0d4..0549e337 100644 --- a/Readme.md +++ b/Readme.md @@ -192,6 +192,36 @@ the following methods are available: - cookieconsent`.hideSettings()` Additional methods for an easier management of your scripts and cookie settings (expand them to see usage example): +-
cookieconsent.accept(<accepted_categories>, <optional_rejected_categories>) [v2.5.0+] +

+ + - accepted_categories: `string` or `string[]` + - rejected_categories: `string[]` - optional + +
+ + Note: **all categories marked as `readonly` will ALWAYS be enabled/accepted regardless of the categories provided inside the `.accept()` API call.** + + Examples: + + ```javascript + cookieconsent.accept('all'); // accept all categories + cookieconsent.accept([]); // accept none (reject all) + cookieconsent.accept('analytics'); // accept only analytics category + cookieconsent.accept(['cat_1', 'cat_2']); // accept only these 2 categories + cookieconsent.accept(); // accept all currently selected categories inside modal + + cookieconsent.accept('all', ['analytics']); // accept all except "analytics" category + cookieconsent.accept('all', ['cat_1', 'cat_2']); // accept all except these 2 categories + ``` + + How to later reject a specific category (cookieconsent alredy accepted)? Same as above: + + ```javascript + cookieconsent.accept('all', ['targeting']); // opt out of targeting category + ``` +

+
-
cookieconsent.allowedCategory(<category_name>)

@@ -233,6 +263,26 @@ Additional methods for an easier management of your scripts and cookie settings ```

+-
cookieconsent.eraseCookies(<cookie_names>, <optional_path>, <optional_domains>) [v2.5.0+] +

+ + - cookie_names: `string[]` + - path: `string` - optional + - domains: `string[]` - optional + +
+ + Examples: + + ```javascript + cookieconsent.eraseCookies(['cc_cookies']); // erase "cc_cookie" if it exists + cookieconsent.eraseCookies(['cookie1', 'cookie2']); // erase these 2 cookies + + cookieconsent.eraseCookies(['cc_cookie'], "/demo"); + cookieconsent.eraseCookies(['cc_cookie'], "/demo", [location.hostname]); + ``` +

+
-
cookieconsent.loadScript(<path>, <callback_function>, <optional_custom_attributes>)

From f2aa50a0f4cc2c2070adb2b76e0288c084de74e3 Mon Sep 17 00:00:00 2001 From: Orest Bida Date: Fri, 27 Aug 2021 19:14:27 +0200 Subject: [PATCH 12/17] how to: revisions and reject all btn inside settings modal --- Readme.md | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/Readme.md b/Readme.md index 0549e337..77fbebe9 100644 --- a/Readme.md +++ b/Readme.md @@ -26,7 +26,8 @@ A __lightweight__ & __gdpr compliant__ cookie consent plugin written in plain ja 7. [Configuration examples](#full-example-configurations) (work-in-progress) - Configuration with [Google analytics](#full-example-configurations) - Configuration with [explicit `accept all` and `accept necessary only` buttons](#explicit-consent) - - Configuration with embedded full cookie-policy + - Configuration with embedded full cookie-policy +8. [How to enable/manage revisions](#how-to-enablemanage-revisions) 8. [FAQ](#faq) 9. [License](#license) @@ -80,6 +81,7 @@ A __lightweight__ & __gdpr compliant__ cookie consent plugin written in plain ja title : 'Cookie settings', save_settings_btn : "Save settings", accept_all_btn : "Accept all", + reject_all_btn : "Reject all", // optional, [v.2.5.0 +] close_btn_label: "Close", blocks : [ { @@ -121,12 +123,12 @@ You can download the [latest version](https://github.com/orestbida/cookieconsent javascript : ```html -https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@v2.4.7/dist/cookieconsent.js +https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@v2.5.0/dist/cookieconsent.js ``` stylesheet : ```html -https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@v2.4.7/dist/cookieconsent.css +https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@v2.5.0/dist/cookieconsent.css ``` ## Layout options & customization @@ -318,6 +320,7 @@ Below a table which sums up all of the available options (must be passed to the | `cookie_same_site` | string | "Lax" | SameSite attribute | | `theme_css` | string | - | Specify path to the .css file | | `force_consent` | boolean | false | Enable if you want to block page navigation until user action (check [faq](#faq) for a proper implementation) | +| `revision` | number | 0 | Specify this option to enable revisions. [Check below](#how-to-enablemanage-revisions) for a proper usage | | `current_lang` | string | - | Specify one of the languages you have defined (can also be dynamic): `'en'`, `'de'` ... | | `auto_language` | boolean | false | Automatically grab the language based on the user's browser language, if language is not defined => use specified `current_lang` | | `autoclear_cookies` | boolean | false | Enable if you want to automatically delete cookies when user opts-out of a specific category inside cookie settings | @@ -384,6 +387,7 @@ Below a table which sums up all of the available options (must be passed to the title : 'Cookie preferences', save_settings_btn : "Save settings", accept_all_btn : "Accept all", + reject_all_btn : "Reject all", // optional, [v.2.5.0 +] cookie_table_headers : [ {col1: "Name" }, {col2: "Domain" }, @@ -583,6 +587,7 @@ cookieconsent.run({ title : 'Cookie preferences ...', save_settings_btn : "Save settings", accept_all_btn : "Accept all", + reject_all_btn: "Reject all", // optional, [v.2.5.0 +] blocks : [ { title : "First block title ...", @@ -613,6 +618,43 @@ cookieconsent.run({

+## How to enable/manage revisions + +- default revision number is 0 +- if saved revision number inside the existing cookie is different from the one you just specified => consent modal will be shown. + +1. Enable revisions by specifying a valid `revision` parameter: + + ```javascript + cookieconsent.run({ + ... + revision: 1, + ... + }) + ``` + +2. Set a valid `revision_message` parameter (optional) inside `consent_modal`, and put the following `{{revision_message}}` placeholder somewhere inside `description`: + + ```javascript + cookieconsent.run({ + ... + revision: 1, + ... + languages : { + en : { + consent_modal : { + ... + description: "Usual description ... {{revision_message}}" + revision_message: "
Dude, my terms have changed. Sorry for bothering you again!", + ... + }, + ... + } + } + ... + }) + ``` + ## FAQ @@ -699,6 +741,29 @@ cookieconsent.run({ }); ``` +

+ +-
How to add a "reject all" button inside settings modal +

+ + You need to specify `reject_all_btn` inside `settings_modal`: + + ```javascript + cookieconsent.run({ + ... + languages : { + en : { + ... + settings_modal : { + ... + reject_all_btn : "Reject all", + ... + } + } + } + }) + ``` +

-
Make consent required (block page navigation until action) From d832116427add9244dc4a623606b0f1687e6bdce Mon Sep 17 00:00:00 2001 From: Orest Bida Date: Fri, 27 Aug 2021 19:17:37 +0200 Subject: [PATCH 13/17] fix typos --- Readme.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Readme.md b/Readme.md index 77fbebe9..33060d7e 100644 --- a/Readme.md +++ b/Readme.md @@ -28,13 +28,13 @@ A __lightweight__ & __gdpr compliant__ cookie consent plugin written in plain ja - Configuration with [explicit `accept all` and `accept necessary only` buttons](#explicit-consent) - Configuration with embedded full cookie-policy 8. [How to enable/manage revisions](#how-to-enablemanage-revisions) -8. [FAQ](#faq) -9. [License](#license) +9. [FAQ](#faq) +10. [License](#license) ## Key features - __Lightweight__ - __Cross-browser__ support (IE8+) -- __Standalone__ (no external dependecies needed) +- __Standalone__ (no external dependencies needed) - __GDPR compliant__ - __Support for multi language__ - __[WAI-ARIA](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/WAI-ARIA_basics) compliant__ @@ -217,7 +217,7 @@ Additional methods for an easier management of your scripts and cookie settings cookieconsent.accept('all', ['cat_1', 'cat_2']); // accept all except these 2 categories ``` - How to later reject a specific category (cookieconsent alredy accepted)? Same as above: + How to later reject a specific category (cookieconsent already accepted)? Same as above: ```javascript cookieconsent.accept('all', ['targeting']); // opt out of targeting category @@ -327,8 +327,8 @@ Below a table which sums up all of the available options (must be passed to the | `page_scripts` | boolean | false | Enable if you want to easily `manage existing + From 40024fe07ccd75218cd04abde25b360521cbb733 Mon Sep 17 00:00:00 2001 From: Orest Bida Date: Fri, 27 Aug 2021 19:56:28 +0200 Subject: [PATCH 16/17] fix missing comma --- Readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 33060d7e..89bf3251 100644 --- a/Readme.md +++ b/Readme.md @@ -633,7 +633,7 @@ cookieconsent.run({ }) ``` -2. Set a valid `revision_message` parameter (optional) inside `consent_modal`, and put the following `{{revision_message}}` placeholder somewhere inside `description`: +2. Set a valid `revision_message` parameter (optional) inside `consent_modal`, and put the following placeholder `{{revision_message}}` somewhere inside `description`: ```javascript cookieconsent.run({ @@ -644,7 +644,7 @@ cookieconsent.run({ en : { consent_modal : { ... - description: "Usual description ... {{revision_message}}" + description: "Usual description ... {{revision_message}}", revision_message: "
Dude, my terms have changed. Sorry for bothering you again!", ... }, From c4cd9f4765a526ab1baebcfb141fd0c9b7a82e53 Mon Sep 17 00:00:00 2001 From: Orest Bida Date: Fri, 27 Aug 2021 20:07:21 +0200 Subject: [PATCH 17/17] update demo files --- demo/app2.js | 12 +++++------ demo/index.html | 56 +++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/demo/app2.js b/demo/app2.js index 3ba0be35..d10a78ca 100644 --- a/demo/app2.js +++ b/demo/app2.js @@ -29,13 +29,13 @@ cc.run({ /* Basic gui options */ gui_options : { consent_modal : { - layout : 'box', // box(default),cloud,bar - position : 'bottom right', // bottom(default),top + left,right,center:=> examples: 'bottom' or 'top right' - transition : 'slide' // zoom(default),slide + layout : 'cloud', // box(default),cloud,bar + position : 'bottom center', // bottom(default),top + left,right,center:=> examples: 'bottom' or 'top right' + transition : 'slide' // zoom(default),slide }, settings_modal : { - layout : 'box', // box(default),bar - //position: 'left', // right(default),left (available only if bar layout selected) + layout : 'bar', // box(default),bar + position: 'left', // right(default),left (available only if bar layout selected) transition : 'slide' // zoom(default),slide } }, @@ -78,7 +78,7 @@ cc.run({ languages : { 'en' : { consent_modal : { - title : "Hello traveler, it's time for some nice cookies", + title : "Hello traveler, it's cookie time!", description : 'Hi, this website uses essential cookies to ensure its proper operation and tracking cookies to understand how you interact with it. The latter will be set only after consent. Privacy policy', primary_btn: { text: 'Accept all', diff --git a/demo/index.html b/demo/index.html index 16ccea02..d28ec7d6 100644 --- a/demo/index.html +++ b/demo/index.html @@ -8,6 +8,14 @@ + -