From de96bab908954590f842f5d088b6f50d57372c56 Mon Sep 17 00:00:00 2001 From: Orest Bida Date: Sun, 27 Feb 2022 23:04:00 +0100 Subject: [PATCH 01/10] Added new fields: `consent_uuid`, `consent_date` and `last_consent_update` --- dist/cookieconsent.js | 75 +++++++++++----------- src/cookieconsent.js | 144 +++++++++++++++++++++++++++++++++--------- 2 files changed, 152 insertions(+), 67 deletions(-) diff --git a/dist/cookieconsent.js b/dist/cookieconsent.js index 5b9be8b9..0ec070eb 100644 --- a/dist/cookieconsent.js +++ b/dist/cookieconsent.js @@ -4,40 +4,41 @@ Author Orest Bida Released under the MIT License */ -(function(){var hb=function(ab){var f={mode:"opt-in",current_lang:"en",auto_language:null,autorun:!0,page_scripts:!0,hide_from_bots:!0,cookie_name:"cc_cookie",cookie_expiration:182,cookie_domain:window.location.hostname,cookie_path:"/",cookie_same_site:"Lax",use_rfc_cookie:!1,autoclear_cookies:!0,revision:0,script_selector:"data-cookiecategory"},n={},g,u={},B=null,J=!1,O=!1,ma=!1,Ba=!1,na=!1,v,X,T,oa,Ca,Da,Qa=!1,ha=!0,U=[],wa=!1,Ea,Fa=[],Ra=[],Ga=[],Sa=!1,pa,Ha,Ia=[],ia=[],P=[],G=[],xa=[],qa=document.documentElement, -Q,ra,x,Y,sa,V,R,S,Z,E,K,ta,ja,ka,y,aa,ba,ca,da,Ta=function(a){function b(l){return(a||document).querySelectorAll('a[data-cc="'+l+'"], button[data-cc="'+l+'"]')}function c(l,q){l.preventDefault?l.preventDefault():l.returnValue=!1;n.accept(q);n.hideSettings();n.hide()}for(var d=b("c-settings"),e=b("accept-all"),m=b("accept-necessary"),p=b("accept-custom"),k=0;k
\x3c!--\x3e
\x3c!--
\x3c!--\x3e
\x3c!-->a/4).toString(16)})},ib=function(a,b){return"browser"===f.auto_language?(b=navigator.language||navigator.browserLanguage, +2 retrieve category states from cookie + * If consent is valid => retrieve category states from cookie * Otherwise use states defined in the user_config. object */ - if(cookie_consent_accepted){ + if(!invalid_consent){ if(_inArray(saved_cookie_content['categories'], cookie_category) > -1){ block_switch.checked = true; !new_settings_blocks && toggle_states.push(true); @@ -1115,20 +1152,35 @@ /** * Clear cookies when settings/preferences change */ - if(cookie_consent_accepted && _config.autoclear_cookies && changed_settings.length > 0) + if(!invalid_consent && _config.autoclear_cookies && changed_settings.length > 0) _autoclearCookies(); + if(!consent_date) consent_date = new Date(); + if(!consent_uuid) consent_uuid = _uuidv4(); + saved_cookie_content = { "categories": accepted_categories, "revision": _config.revision, "data": cookie_data, - "rfc_cookie": _config.use_rfc_cookie + "rfc_cookie": _config.use_rfc_cookie, + "consent_date": consent_date.toISOString(), + "consent_uuid": consent_uuid } // save cookie with preferences 'categories' (only if never accepted or settings were updated) - if(!cookie_consent_accepted || changed_settings.length > 0 || !valid_revision){ + if(invalid_consent || changed_settings.length > 0){ valid_revision = true; + /** + * Update "last_consent_update" only if it is invalid (after t) + */ + if(!last_consent_update) + last_consent_update = consent_date; + else + last_consent_update = new Date(); + + saved_cookie_content['last_consent_update'] = last_consent_update.toISOString(); + /** * Update accept type */ @@ -1136,12 +1188,14 @@ _setCookie(_config.cookie_name, JSON.stringify(saved_cookie_content)); _manageExistingScripts(); + + //_printConsentDateHTML(); } - if(!cookie_consent_accepted){ + if(invalid_consent){ /** - * Delete unused/"zombie" cookies the very-first time + * Delete unused/"zombie" cookies if consent is not valid (not yet expressed or cookie has expired) */ if(_config.autoclear_cookies) _autoclearCookies(true); @@ -1152,7 +1206,10 @@ if(typeof onAccept === 'function') onAccept(saved_cookie_content); - cookie_consent_accepted = true; + /** + * Set consent as valid + */ + invalid_consent = false; if(_config.mode === 'opt-in') return; } @@ -1200,6 +1257,17 @@ return el; } + /** + * Generate RFC4122-compliant UUIDs. + * https://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid?page=1&tab=votes#tab-top + * @returns {string} + */ + var _uuidv4 = function(){ + return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, function(c){ + return (c ^ (window.crypto || window.msCrypto).getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) + }); + } + /** * Resolve which language should be used. * @@ -1393,7 +1461,7 @@ */ _cookieconsent.allowedCategory = function(cookie_category){ - if(cookie_consent_accepted || _config.mode === 'opt-in') + if(!invalid_consent || _config.mode === 'opt-in') var allowed_categories = JSON.parse(_getCookie(_config.cookie_name, 'one', true) || '{}')['categories'] || [] else // mode is 'opt-out' var allowed_categories = default_enabled_categories; @@ -1415,25 +1483,35 @@ // Retrieve cookie value (if set) saved_cookie_content = JSON.parse(_getCookie(_config.cookie_name, 'one', true) || "{}"); - cookie_consent_accepted = saved_cookie_content['categories'] !== undefined; - /** - * Immediately retrieve the 'data' field from cookie - * (since this value is allowed to be accessed/used before the .run method) - */ + // Retrieve "consent_uuid" + consent_uuid = saved_cookie_content['consent_uuid']; + + // If "consent_uuid" is present => assume that consent was previously given + var cookie_consent_accepted = consent_uuid !== undefined; + + // Retrieve "consent_date" + consent_date = saved_cookie_content['consent_date']; + consent_date && (consent_date = new Date(consent_date)); + + // Retrieve "last_consent_update" + last_consent_update = saved_cookie_content['last_consent_update']; + last_consent_update && (last_consent_update = new Date(last_consent_update)); + + // Retrieve "data" cookie_data = saved_cookie_content['data'] !== undefined ? saved_cookie_content['data'] : null; - // Compare current revision with the one retrieved from cookie - valid_revision = typeof user_config['revision'] === "number" - ? cookie_consent_accepted - ? user_config['revision'] > -1 - ? saved_cookie_content['revision'] === _config.revision - : true - : true - : true; + // If revision is enabled and current value == saved value inside the cookie => revision is valid + if( + typeof user_config['revision'] === 'number' + && user_config['revision'] > -1 + && saved_cookie_content['revision'] === _config.revision + ){ + valid_revision = true; + } - // If invalid revision or cookie is empty => create consent modal - consent_modal_exists = (!cookie_consent_accepted || !valid_revision); + // If consent is not valid => create consent modal + consent_modal_exists = invalid_consent = (!cookie_consent_accepted || !valid_revision || !consent_date || !last_consent_update || !consent_uuid); // Generate cookie-settings dom (& consent modal) _createCookieConsentHTML(); @@ -1452,7 +1530,8 @@ // Accessibility :=> if tab pressed => trap focus inside modal setTimeout(function(){_handleFocusTrap();}, 100); - if(cookie_consent_accepted && valid_revision){ + // If consent is valid + if(!invalid_consent){ var rfc_prop_exists = typeof saved_cookie_content['rfc_cookie'] === "boolean"; /* @@ -1473,10 +1552,14 @@ if(typeof onAccept === 'function') onAccept(saved_cookie_content); + _log("CookieConsent [NOTICE]: consent already given!", saved_cookie_content); - }else if(_config.mode === 'opt-out'){ - _log("CookieConsent [CONFIG] mode='" + _config.mode + "', default enabled categories:", default_enabled_categories); - _manageExistingScripts(default_enabled_categories); + }else{ + if(_config.mode === 'opt-out'){ + _log("CookieConsent [CONFIG] mode='" + _config.mode + "', default enabled categories:", default_enabled_categories); + _manageExistingScripts(default_enabled_categories); + } + _log("CookieConsent [NOTICE]: ask for consent!"); } }else{ _log("CookieConsent [NOTICE]: cookie consent already attached to body!"); @@ -2056,7 +2139,8 @@ document.cookie = cookieStr; - _log("CookieConsent [SET_COOKIE]: cookie "+ name + "='" + value + "' was set! Expires after " + cookie_expiration + " days"); + _log("CookieConsent [SET_COOKIE]: cookie '" + name + "'=", JSON.parse(value)); + _log("CookieConsent [SET_COOKIE]: '" + name + "' expires after " + cookie_expiration + " day(s)"); } /** From ca24f7287a5c3e5b59da268f8762589cf3f6c97f Mon Sep 17 00:00:00 2001 From: Orest Bida Date: Thu, 3 Mar 2022 22:28:30 +0100 Subject: [PATCH 02/10] Fix revision broken in last commits --- src/cookieconsent.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cookieconsent.js b/src/cookieconsent.js index f9ddd15b..45aa5167 100644 --- a/src/cookieconsent.js +++ b/src/cookieconsent.js @@ -1501,13 +1501,13 @@ // Retrieve "data" cookie_data = saved_cookie_content['data'] !== undefined ? saved_cookie_content['data'] : null; - // If revision is enabled and current value == saved value inside the cookie => revision is valid + // If revision is enabled and current value !== saved value inside the cookie => revision is not valid if( typeof user_config['revision'] === 'number' && user_config['revision'] > -1 - && saved_cookie_content['revision'] === _config.revision + && saved_cookie_content['revision'] !== _config.revision ){ - valid_revision = true; + valid_revision = false; } // If consent is not valid => create consent modal From 1d5e5f413ad9b1454ad3836a065953bb79d123ad Mon Sep 17 00:00:00 2001 From: Orest Bida Date: Fri, 4 Mar 2022 18:01:15 +0100 Subject: [PATCH 03/10] Cleanup (removed feature detection for old browser) & code refactoring --- src/cookieconsent.js | 101 +++++++------------------------------------ 1 file changed, 15 insertions(+), 86 deletions(-) diff --git a/src/cookieconsent.js b/src/cookieconsent.js index 45aa5167..ada2c515 100644 --- a/src/cookieconsent.js +++ b/src/cookieconsent.js @@ -292,7 +292,7 @@ for(var i=0; i revision is not valid - if( - typeof user_config['revision'] === 'number' - && user_config['revision'] > -1 - && saved_cookie_content['revision'] !== _config.revision - ){ + if(revision_enabled && saved_cookie_content['revision'] !== _config.revision){ valid_revision = false; } @@ -1740,43 +1736,6 @@ return set; } - /** - * Forcefully set a specific revision and show consent modal - * @param {number} new_revision - * @param {boolean} [prompt_consent] - * @returns {boolean} - */ - var _setRevision = function(new_revision, prompt_consent, message){ - - // If plugin has been initialized and new revision is valid - if( - main_container - && typeof new_revision === "number" - && saved_cookie_content['revision'] !== new_revision - ){ - - revision_enabled = true; - revision_message = message; - valid_revision = false; - _config.revision = new_revision; - - // Show consent modal ? - if(prompt_consent === true){ - _createConsentModal(user_config); - _guiManager(user_config['gui_options'], true); - _getModalFocusableData(); - _cookieconsent.show(); - }else { - // If revision was modified, save cookie with the new revision - _cookieconsent.accept(); - } - - return true; - } - - return false; - } - /** * Helper method to set a variety of fields * @param {string} field @@ -1884,7 +1843,7 @@ * Dynamically load script (append to head) * @param {string} src * @param {scriptLoaded} callback - * @param {string[]} attrs + * @param {object[]} [attrs] Custom attributes */ _cookieconsent.loadScript = function(src, callback, attrs){ @@ -1904,16 +1863,7 @@ // if callback function defined => run callback onload if(function_defined){ - if(script.readyState) { // only required for IE <9 - script.onreadystatechange = function() { - if ( script.readyState === "loaded" || script.readyState === "complete" ) { - script.onreadystatechange = null; - callback(); - } - }; - }else{ //Others - script.onload = callback; - } + script.onload = callback; } script.src = src; @@ -1921,7 +1871,7 @@ /** * Append script to head */ - (document.head ? document.head : document.getElementsByTagName('head')[0]).appendChild(script); + document.head.appendChild(script); }else{ function_defined && callback(); } @@ -2148,8 +2098,8 @@ * 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 {boolean} get_value - set to true to obtain its value + * @param {string} filter 'one' or 'all' + * @param {boolean} [get_value] set to true to obtain its value * @returns {string|string[]} */ var _getCookie = function(name, filter, get_value) { @@ -2221,20 +2171,10 @@ * @param {Element} elem * @param {string} event * @param {eventFired} fn - * @param {boolean} passive + * @param {boolean} [isPasive] */ - var _addEvent = function(elem, event, fn, _passive) { - var passive = _passive === true; - - if (elem.addEventListener) { - passive ? elem.addEventListener(event, fn , { passive: true }) : elem.addEventListener(event, fn, false); - } else { - /** - * For old browser, add 'on' before event: - * 'click':=> 'onclick' - */ - elem.attachEvent("on" + event, fn); - } + var _addEvent = function(elem, event, fn, isPasive) { + elem.addEventListener(event, fn , isPasive === true ? { passive: true } : false); } /** @@ -2243,10 +2183,7 @@ */ var _getKeys = function(obj){ if(typeof obj === "object"){ - var keys = [], i = 0; - for (var key in obj) - keys[i++] = key; - return keys; + return Object.keys(obj); } } @@ -2256,12 +2193,7 @@ * @param {string} classname */ var _addClass = function (elem, classname){ - if(elem.classList) - elem.classList.add(classname) - else{ - if(!_hasClass(elem, classname)) - elem.className += ' '+classname; - } + elem.classList.add(classname); } /** @@ -2270,7 +2202,7 @@ * @param {string} classname */ var _removeClass = function (el, className) { - el.classList ? el.classList.remove(className) : el.className = el.className.replace(new RegExp('(\\s|^)' + className + '(\\s|$)'), ' '); + el.classList.remove(className); } /** @@ -2279,10 +2211,7 @@ * @param {string} className */ var _hasClass = function(el, className) { - if (el.classList) { - return el.classList.contains(className); - } - return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)')); + return el.classList.contains(className); } return _cookieconsent; From 7b42fcb727a2d070382276dd6496bfdda23b2722 Mon Sep 17 00:00:00 2001 From: "voraton.l" Date: Thu, 5 May 2022 15:41:06 +0700 Subject: [PATCH 04/10] Add typescript support for lib --- type.d.ts | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 type.d.ts diff --git a/type.d.ts b/type.d.ts new file mode 100644 index 00000000..d358d7ae --- /dev/null +++ b/type.d.ts @@ -0,0 +1,145 @@ +export {} + +declare global { + type MODE = 'opt-in' | 'opt-out' + + type AUTO_LANGUAGE_ORIGIN = 'browser' | 'document' + + type ModalLayout = 'box' | 'cloud' | 'bar' + + type ModalPosition = 'bottom left' | 'bottom right' | 'bottom center' | 'middle left' | 'middle right' | 'middle center' | 'top left' | 'top right' | 'top center' + + type GUITransition = 'zoom' | 'slide' + + type SettingLayout = 'box' | 'bar' + + type SettingPosition = 'left' | 'right' + + interface SavedCookieContent { + categories: string[] + revision: number + data?: null | Record | string> + rfc_cookie: boolean + consent_date: string + consent_uuid: string + last_consent_update: string + } + + interface GUIOptions { + consent_modal?: { + layout?: ModalLayout + position?: ModalPosition + transition?: GUITransition + swap_buttons?: boolean + }, + settings_modal?: { + layout?: SettingLayout + position?: SettingPosition + transition?: GUITransition + } + } + + interface UserPreferences { + accept_type: string + accepted_categories: string[] + rejected_categories: string[] + } + + type PrimaryButtonRole = 'accept_selected' | 'accept_all' + + type SecondaryButtonRole = 'settings' | 'accept_necessary' + + interface ButtonSetting { + text: string + role: Role + } + + interface ConsentModalLanguageSetting { + title?: string + description?: string + primary_btn?: ButtonSetting + secondary_btn?: ButtonSetting + revision_message?: string + } + + interface ToggleSetting { + value: string + enabled?: boolean + readonly?: boolean + } + + interface BlockSetting { + title: string + description: string + toggle?: ToggleSetting + } + + interface SettingsModalLanguageSetting { + title?: string + save_settings_btn?: string + accept_all_btn?: string + blocks?: BlockSetting[] + cookie_table_headers?: Record[] + cookie_table?: Record[] + } + + interface LanguageSetting { + consent_modal?: ConsentModalLanguageSetting + settings_modal?: SettingsModalLanguageSetting + } + + interface UserConfig { + autorun?: boolean + delay?: number + mode?: MODE + cookie_expiration?: number + cookie_necessary_only_expiration?: number + cookie_path?: string + cookie_domain?: string + cookie_same_site?: string + use_rfc_cookie?: boolean + force_consent?: boolean + revision?: number + current_lang?: string + auto_language?: string + autoclear_cookies?: boolean + page_scripts?: boolean + remove_cookie_tables?: boolean + hide_from_bots?: boolean + gui_options?: GUIOptions + onAccept?: (savedCookieContent: SavedCookieContent) => void + onChange?: (cookie: SavedCookieContent, changedCookieCategories: string[]) => void + onFirstAction? :(userPreferences: UserPreferences, cookie: SavedCookieContent) => void + languages?: Record + } + + interface ScriptAttribute { + name: string + value: any + } + + interface CookieConsent { + run(config: UserConfig): void + showSettings(delay: number): void + accept(_categories: string | string[], _exclusions?: string[]): void + hideSettings(): void + hide(): void + updateLanguage(lang: string, force: boolean): boolean + getUserPreferences(): UserPreferences + loadScript(src: string, callback: () => void | typeof onload, attrs?: ScriptAttribute[]): void + updateScripts(): void + show(delay?: number, create_modal?: boolean): void + eraseCookies(_cookies: string | string[], _path?: string, _domain?: string): void + validCookie(cookie_name: string): boolean + allowedCategory(cookie_category: string): boolean + set(field: string, data: Record): boolean + get(field: string, cookie_name?: string): Record + getConfig(field: Field): UserConfig[Field] + } + + function initCookieConsent(root?: HTMLElement):CookieConsent + + interface Window { + initCookieConsent: typeof initCookieConsent + } +} From 243a1c03008b75bfecfe4d80ad9715c86a75dc4f Mon Sep 17 00:00:00 2001 From: "voraton.l" Date: Thu, 5 May 2022 15:42:26 +0700 Subject: [PATCH 05/10] Fix indent --- type.d.ts | 166 +++++++++++++++++++++++++++--------------------------- 1 file changed, 83 insertions(+), 83 deletions(-) diff --git a/type.d.ts b/type.d.ts index d358d7ae..946224e5 100644 --- a/type.d.ts +++ b/type.d.ts @@ -16,33 +16,33 @@ declare global { type SettingPosition = 'left' | 'right' interface SavedCookieContent { - categories: string[] - revision: number - data?: null | Record | string> - rfc_cookie: boolean - consent_date: string - consent_uuid: string - last_consent_update: string + categories: string[] + revision: number + data?: null | Record | string> + rfc_cookie: boolean + consent_date: string + consent_uuid: string + last_consent_update: string } interface GUIOptions { - consent_modal?: { - layout?: ModalLayout - position?: ModalPosition - transition?: GUITransition - swap_buttons?: boolean - }, - settings_modal?: { - layout?: SettingLayout - position?: SettingPosition - transition?: GUITransition - } + consent_modal?: { + layout?: ModalLayout + position?: ModalPosition + transition?: GUITransition + swap_buttons?: boolean + }, + settings_modal?: { + layout?: SettingLayout + position?: SettingPosition + transition?: GUITransition + } } interface UserPreferences { - accept_type: string - accepted_categories: string[] - rejected_categories: string[] + accept_type: string + accepted_categories: string[] + rejected_categories: string[] } type PrimaryButtonRole = 'accept_selected' | 'accept_all' @@ -50,96 +50,96 @@ declare global { type SecondaryButtonRole = 'settings' | 'accept_necessary' interface ButtonSetting { - text: string - role: Role + text: string + role: Role } interface ConsentModalLanguageSetting { - title?: string - description?: string - primary_btn?: ButtonSetting - secondary_btn?: ButtonSetting - revision_message?: string + title?: string + description?: string + primary_btn?: ButtonSetting + secondary_btn?: ButtonSetting + revision_message?: string } interface ToggleSetting { - value: string - enabled?: boolean - readonly?: boolean + value: string + enabled?: boolean + readonly?: boolean } interface BlockSetting { - title: string - description: string - toggle?: ToggleSetting + title: string + description: string + toggle?: ToggleSetting } interface SettingsModalLanguageSetting { - title?: string - save_settings_btn?: string - accept_all_btn?: string - blocks?: BlockSetting[] - cookie_table_headers?: Record[] - cookie_table?: Record[] + title?: string + save_settings_btn?: string + accept_all_btn?: string + blocks?: BlockSetting[] + cookie_table_headers?: Record[] + cookie_table?: Record[] } interface LanguageSetting { - consent_modal?: ConsentModalLanguageSetting - settings_modal?: SettingsModalLanguageSetting + consent_modal?: ConsentModalLanguageSetting + settings_modal?: SettingsModalLanguageSetting } interface UserConfig { - autorun?: boolean - delay?: number - mode?: MODE - cookie_expiration?: number - cookie_necessary_only_expiration?: number - cookie_path?: string - cookie_domain?: string - cookie_same_site?: string - use_rfc_cookie?: boolean - force_consent?: boolean - revision?: number - current_lang?: string - auto_language?: string - autoclear_cookies?: boolean - page_scripts?: boolean - remove_cookie_tables?: boolean - hide_from_bots?: boolean - gui_options?: GUIOptions - onAccept?: (savedCookieContent: SavedCookieContent) => void - onChange?: (cookie: SavedCookieContent, changedCookieCategories: string[]) => void - onFirstAction? :(userPreferences: UserPreferences, cookie: SavedCookieContent) => void - languages?: Record + autorun?: boolean + delay?: number + mode?: MODE + cookie_expiration?: number + cookie_necessary_only_expiration?: number + cookie_path?: string + cookie_domain?: string + cookie_same_site?: string + use_rfc_cookie?: boolean + force_consent?: boolean + revision?: number + current_lang?: string + auto_language?: string + autoclear_cookies?: boolean + page_scripts?: boolean + remove_cookie_tables?: boolean + hide_from_bots?: boolean + gui_options?: GUIOptions + onAccept?: (savedCookieContent: SavedCookieContent) => void + onChange?: (cookie: SavedCookieContent, changedCookieCategories: string[]) => void + onFirstAction? :(userPreferences: UserPreferences, cookie: SavedCookieContent) => void + languages?: Record } interface ScriptAttribute { - name: string - value: any + name: string + value: any } interface CookieConsent { - run(config: UserConfig): void - showSettings(delay: number): void - accept(_categories: string | string[], _exclusions?: string[]): void - hideSettings(): void - hide(): void - updateLanguage(lang: string, force: boolean): boolean - getUserPreferences(): UserPreferences - loadScript(src: string, callback: () => void | typeof onload, attrs?: ScriptAttribute[]): void - updateScripts(): void - show(delay?: number, create_modal?: boolean): void - eraseCookies(_cookies: string | string[], _path?: string, _domain?: string): void - validCookie(cookie_name: string): boolean - allowedCategory(cookie_category: string): boolean - set(field: string, data: Record): boolean - get(field: string, cookie_name?: string): Record - getConfig(field: Field): UserConfig[Field] + run(config: UserConfig): void + showSettings(delay: number): void + accept(_categories: string | string[], _exclusions?: string[]): void + hideSettings(): void + hide(): void + updateLanguage(lang: string, force: boolean): boolean + getUserPreferences(): UserPreferences + loadScript(src: string, callback: () => void | typeof onload, attrs?: ScriptAttribute[]): void + updateScripts(): void + show(delay?: number, create_modal?: boolean): void + eraseCookies(_cookies: string | string[], _path?: string, _domain?: string): void + validCookie(cookie_name: string): boolean + allowedCategory(cookie_category: string): boolean + set(field: string, data: Record): boolean + get(field: string, cookie_name?: string): Record + getConfig(field: Field): UserConfig[Field] } function initCookieConsent(root?: HTMLElement):CookieConsent interface Window { - initCookieConsent: typeof initCookieConsent + initCookieConsent: typeof initCookieConsent } } From 263ec7c2e7ad1c8e1eee5281526d3a0675b1fd8b Mon Sep 17 00:00:00 2001 From: "voraton.l" Date: Wed, 11 May 2022 13:41:19 +0700 Subject: [PATCH 06/10] Add missing type --- type.d.ts | 169 +++++++++++++++++++++++++++--------------------------- 1 file changed, 85 insertions(+), 84 deletions(-) diff --git a/type.d.ts b/type.d.ts index 946224e5..34d64d88 100644 --- a/type.d.ts +++ b/type.d.ts @@ -16,33 +16,33 @@ declare global { type SettingPosition = 'left' | 'right' interface SavedCookieContent { - categories: string[] - revision: number - data?: null | Record | string> - rfc_cookie: boolean - consent_date: string - consent_uuid: string - last_consent_update: string + categories: string[] + revision: number + data?: null | Record | string> + rfc_cookie: boolean + consent_date: string + consent_uuid: string + last_consent_update: string } interface GUIOptions { - consent_modal?: { - layout?: ModalLayout - position?: ModalPosition - transition?: GUITransition - swap_buttons?: boolean - }, - settings_modal?: { - layout?: SettingLayout - position?: SettingPosition - transition?: GUITransition - } + consent_modal?: { + layout?: ModalLayout + position?: ModalPosition + transition?: GUITransition + swap_buttons?: boolean + }, + settings_modal?: { + layout?: SettingLayout + position?: SettingPosition + transition?: GUITransition + } } interface UserPreferences { - accept_type: string - accepted_categories: string[] - rejected_categories: string[] + accept_type: string + accepted_categories: string[] + rejected_categories: string[] } type PrimaryButtonRole = 'accept_selected' | 'accept_all' @@ -50,96 +50,97 @@ declare global { type SecondaryButtonRole = 'settings' | 'accept_necessary' interface ButtonSetting { - text: string - role: Role + text: string + role: Role } interface ConsentModalLanguageSetting { - title?: string - description?: string - primary_btn?: ButtonSetting - secondary_btn?: ButtonSetting - revision_message?: string + title?: string + description?: string + primary_btn?: ButtonSetting + secondary_btn?: ButtonSetting + revision_message?: string } interface ToggleSetting { - value: string - enabled?: boolean - readonly?: boolean + value: string + enabled?: boolean + readonly?: boolean } interface BlockSetting { - title: string - description: string - toggle?: ToggleSetting + title: string + description: string + toggle?: ToggleSetting + cookie_table_headers?: Record[] + cookie_table?: Record[] } interface SettingsModalLanguageSetting { - title?: string - save_settings_btn?: string - accept_all_btn?: string - blocks?: BlockSetting[] - cookie_table_headers?: Record[] - cookie_table?: Record[] + title?: string + save_settings_btn?: string + accept_all_btn?: string + reject_all_btn?: string + blocks?: BlockSetting[] } interface LanguageSetting { - consent_modal?: ConsentModalLanguageSetting - settings_modal?: SettingsModalLanguageSetting + consent_modal?: ConsentModalLanguageSetting + settings_modal?: SettingsModalLanguageSetting } interface UserConfig { - autorun?: boolean - delay?: number - mode?: MODE - cookie_expiration?: number - cookie_necessary_only_expiration?: number - cookie_path?: string - cookie_domain?: string - cookie_same_site?: string - use_rfc_cookie?: boolean - force_consent?: boolean - revision?: number - current_lang?: string - auto_language?: string - autoclear_cookies?: boolean - page_scripts?: boolean - remove_cookie_tables?: boolean - hide_from_bots?: boolean - gui_options?: GUIOptions - onAccept?: (savedCookieContent: SavedCookieContent) => void - onChange?: (cookie: SavedCookieContent, changedCookieCategories: string[]) => void - onFirstAction? :(userPreferences: UserPreferences, cookie: SavedCookieContent) => void - languages?: Record + autorun?: boolean + delay?: number + mode?: MODE + cookie_expiration?: number + cookie_necessary_only_expiration?: number + cookie_path?: string + cookie_domain?: string + cookie_same_site?: string + use_rfc_cookie?: boolean + force_consent?: boolean + revision?: number + current_lang?: string + auto_language?: AUTO_LANGUAGE_ORIGIN + autoclear_cookies?: boolean + page_scripts?: boolean + remove_cookie_tables?: boolean + hide_from_bots?: boolean + gui_options?: GUIOptions + onAccept?: (savedCookieContent: SavedCookieContent) => void + onChange?: (cookie: SavedCookieContent, changedCookieCategories: string[]) => void + onFirstAction? :(userPreferences: UserPreferences, cookie: SavedCookieContent) => void + languages?: Record } interface ScriptAttribute { - name: string - value: any + name: string + value: any } interface CookieConsent { - run(config: UserConfig): void - showSettings(delay: number): void - accept(_categories: string | string[], _exclusions?: string[]): void - hideSettings(): void - hide(): void - updateLanguage(lang: string, force: boolean): boolean - getUserPreferences(): UserPreferences - loadScript(src: string, callback: () => void | typeof onload, attrs?: ScriptAttribute[]): void - updateScripts(): void - show(delay?: number, create_modal?: boolean): void - eraseCookies(_cookies: string | string[], _path?: string, _domain?: string): void - validCookie(cookie_name: string): boolean - allowedCategory(cookie_category: string): boolean - set(field: string, data: Record): boolean - get(field: string, cookie_name?: string): Record - getConfig(field: Field): UserConfig[Field] + run(config: UserConfig): void + showSettings(delay: number): void + accept(_categories: string | string[], _exclusions?: string[]): void + hideSettings(): void + hide(): void + updateLanguage(lang: string, force: boolean): boolean + getUserPreferences(): UserPreferences + loadScript(src: string, callback: () => void | typeof onload, attrs?: ScriptAttribute[]): void + updateScripts(): void + show(delay?: number, create_modal?: boolean): void + eraseCookies(_cookies: string | string[], _path?: string, _domain?: string): void + validCookie(cookie_name: string): boolean + allowedCategory(cookie_category: string): boolean + set(field: string, data: Record): boolean + get(field: string, cookie_name?: string): Record + getConfig(field: Field): UserConfig[Field] } - function initCookieConsent(root?: HTMLElement):CookieConsent + function initCookieConsent(root?: HTMLElement): CookieConsent interface Window { - initCookieConsent: typeof initCookieConsent + initCookieConsent: typeof initCookieConsent } } From fb8dde828d52bc7e8eede085ef6fa88965066d4c Mon Sep 17 00:00:00 2001 From: Orest Bida Date: Wed, 22 Jun 2022 18:32:27 +0200 Subject: [PATCH 07/10] Fix nextjs + minor typo --- dist/cookieconsent.js | 75 +++++++++++++++++++++---------------------- src/cookieconsent.js | 8 ++--- 2 files changed, 41 insertions(+), 42 deletions(-) diff --git a/dist/cookieconsent.js b/dist/cookieconsent.js index 0ec070eb..184bf5c9 100644 --- a/dist/cookieconsent.js +++ b/dist/cookieconsent.js @@ -4,41 +4,40 @@ Author Orest Bida Released under the MIT License */ -(function(){var lb=function(db){var f={mode:"opt-in",current_lang:"en",auto_language:null,autorun:!0,page_scripts:!0,hide_from_bots:!0,cookie_name:"cc_cookie",cookie_expiration:182,cookie_domain:window.location.hostname,cookie_path:"/",cookie_same_site:"Lax",use_rfc_cookie:!1,autoclear_cookies:!0,revision:0,script_selector:"data-cookiecategory"},n={},g,t={},B=null,X,Y,na,S=!0,N=!1,oa=!1,Ea=!1,pa=!1,v,Z,T,qa,Fa,Ga,Ta=!1,ya=!0,U=[],za=!1,Ha,Ia=[],Ua=[],Ja=[],Va=!1,ra,Ka,La=[],ja=[],O=[],G=[],Aa=[], -sa=document.documentElement,P,ta,x,aa,ua,V,Q,R,ba,E,J,va,ka,la,y,ca,da,ea,fa,Wa=function(a){function b(l){return(a||document).querySelectorAll('a[data-cc="'+l+'"], button[data-cc="'+l+'"]')}function c(l,q){l.preventDefault?l.preventDefault():l.returnValue=!1;n.accept(q);n.hideSettings();n.hide()}for(var d=b("c-settings"),e=b("accept-all"),m=b("accept-necessary"),p=b("accept-custom"),k=0;k
\x3c!--\x3e
\x3c!-->a/4).toString(16)})},ib=function(a,b){return"browser"===f.auto_language?(b=navigator.language||navigator.browserLanguage, -2
\x3c!--\x3e
\x3c!-->a/4).toString(16)})},gb=function(a,b){return"browser"===e.auto_language?(b=navigator.language||navigator.browserLanguage, +2 Date: Wed, 22 Jun 2022 18:33:24 +0200 Subject: [PATCH 08/10] Move `d.ts` to `types` folder --- package.json | 32 +++++++++++ types/types.d.ts | 146 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+) create mode 100644 package.json create mode 100644 types/types.d.ts diff --git a/package.json b/package.json new file mode 100644 index 00000000..b5c17fda --- /dev/null +++ b/package.json @@ -0,0 +1,32 @@ +{ + "name": "vanilla-cookieconsent", + "version": "v2.8.1", + "description": "🍪 Simple cross-browser cookie-consent plugin written in vanilla js.", + "main": "dist/cookieconsent.js", + "files": [ + "src", + "dist", + "types" + ], + "types": "types/types.d.ts", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://tillsanders@github.com/tillsanders/cookieconsent.git" + }, + "keywords": [ + "cookie", + "consent", + "gdpr", + "banner", + "vanilla" + ], + "author": "Orest Bida", + "license": "MIT", + "bugs": { + "url": "https://github.com/orestbida/cookieconsent/issues" + }, + "homepage": "https://github.com/orestbida/cookieconsent" +} \ No newline at end of file diff --git a/types/types.d.ts b/types/types.d.ts new file mode 100644 index 00000000..650abf93 --- /dev/null +++ b/types/types.d.ts @@ -0,0 +1,146 @@ +export {} + +declare global { + type MODE = 'opt-in' | 'opt-out' + + type AUTO_LANGUAGE_ORIGIN = 'browser' | 'document' + + type ModalLayout = 'box' | 'cloud' | 'bar' + + type ModalPosition = 'bottom left' | 'bottom right' | 'bottom center' | 'middle left' | 'middle right' | 'middle center' | 'top left' | 'top right' | 'top center' + + type GUITransition = 'zoom' | 'slide' + + type SettingLayout = 'box' | 'bar' + + type SettingPosition = 'left' | 'right' + + interface SavedCookieContent { + categories: string[] + revision: number + data?: null | Record | string> + rfc_cookie: boolean + consent_date: string + consent_uuid: string + last_consent_update: string + } + + interface GUIOptions { + consent_modal?: { + layout?: ModalLayout + position?: ModalPosition + transition?: GUITransition + swap_buttons?: boolean + }, + settings_modal?: { + layout?: SettingLayout + position?: SettingPosition + transition?: GUITransition + } + } + + interface UserPreferences { + accept_type: string + accepted_categories: string[] + rejected_categories: string[] + } + + type PrimaryButtonRole = 'accept_selected' | 'accept_all' + + type SecondaryButtonRole = 'settings' | 'accept_necessary' + + interface ButtonSetting { + text: string + role: Role + } + + interface ConsentModalLanguageSetting { + title?: string + description?: string + primary_btn?: ButtonSetting + secondary_btn?: ButtonSetting + revision_message?: string + } + + interface ToggleSetting { + value: string + enabled?: boolean + readonly?: boolean + } + + interface BlockSetting { + title: string + description: string + toggle?: ToggleSetting + cookie_table_headers?: Record[] + cookie_table?: Record[] + } + + interface SettingsModalLanguageSetting { + title?: string + save_settings_btn?: string + accept_all_btn?: string + reject_all_btn?: string + blocks?: BlockSetting[] + } + + interface LanguageSetting { + consent_modal?: ConsentModalLanguageSetting + settings_modal?: SettingsModalLanguageSetting + } + + interface UserConfig { + autorun?: boolean + delay?: number + mode?: MODE + cookie_expiration?: number + cookie_necessary_only_expiration?: number + cookie_path?: string + cookie_domain?: string + cookie_same_site?: string + use_rfc_cookie?: boolean + force_consent?: boolean + revision?: number + current_lang?: string + auto_language?: AUTO_LANGUAGE_ORIGIN + autoclear_cookies?: boolean + page_scripts?: boolean + remove_cookie_tables?: boolean + hide_from_bots?: boolean + gui_options?: GUIOptions + onAccept?: (savedCookieContent: SavedCookieContent) => void + onChange?: (cookie: SavedCookieContent, changedCookieCategories: string[]) => void + onFirstAction? :(userPreferences: UserPreferences, cookie: SavedCookieContent) => void + languages?: Record + } + + interface ScriptAttribute { + name: string + value: any + } + + interface CookieConsent { + run(config: UserConfig): void + showSettings(delay: number): void + accept(_categories: string | string[], _exclusions?: string[]): void + hideSettings(): void + hide(): void + updateLanguage(lang: string, force: boolean): boolean + getUserPreferences(): UserPreferences + loadScript(src: string, callback: () => void | typeof onload, attrs?: ScriptAttribute[]): void + updateScripts(): void + show(delay?: number, create_modal?: boolean): void + eraseCookies(_cookies: string | string[], _path?: string, _domain?: string): void + validCookie(cookie_name: string): boolean + allowedCategory(cookie_category: string): boolean + set(field: string, data: Record): boolean + get(field: string, cookie_name?: string): Record + getConfig(field: Field): UserConfig[Field] + } + + function initCookieConsent(root?: HTMLElement): CookieConsent + + interface Window { + initCookieConsent: typeof initCookieConsent + } +} \ No newline at end of file From f0f94d58d0db29be00f24685fa51740bd1ffe7f1 Mon Sep 17 00:00:00 2001 From: Orest Bida Date: Wed, 22 Jun 2022 18:34:54 +0200 Subject: [PATCH 09/10] Update version to 2.8.1 --- Readme.md | 39 +++++++++++++++++++++++---------------- dist/cookieconsent.js | 2 +- src/cookieconsent.js | 2 +- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/Readme.md b/Readme.md index 99b80105..015e6f11 100644 --- a/Readme.md +++ b/Readme.md @@ -7,7 +7,7 @@
-A __lightweight__ & __gdpr compliant__ cookie consent plugin written in plain javascript. An "all-in-one" solution which also allows you to write your cookie policy inside it without the need of having a dedicated page. +A __lightweight__ & __gdpr compliant__ cookie consent plugin written in plain javascript.
@@ -17,17 +17,20 @@ A __lightweight__ & __gdpr compliant__ cookie consent plugin written in plain ja
## Table of contents -1. [Key features](#key-features) -2. [Installation & Usage](#installation--usage) -4. [Layout options & customization](#layout-options--customization) -5. [API methods](#api-methods) -6. [Available callbacks](#available-callbacks) -7. [All configuration options](#all-configuration-options) -8. [How to block/manage scripts](#how-to-blockmanage-scripts) -9. [Configuration examples](#full-example-configurations) -10. [How to enable/manage revisions](#how-to-enablemanage-revisions) -11. [FAQ](#faq) -12. [License](#license) +- [Table of contents](#table-of-contents) +- [Key features](#key-features) +- [Installation & Usage](#installation--usage) +- [Layout options & customization](#layout-options--customization) +- [How to block/manage scripts](#how-to-blockmanage-scripts) +- [API methods](#api-methods) +- [Available `data-cc` actions](#available-data-cc-actions) +- [Available callbacks](#available-callbacks) + - [All configuration options](#all-configuration-options) +- [Full example configurations](#full-example-configurations) + - [How to configure languages & cookie settings](#how-to-configure-languages--cookie-settings) +- [How to enable/manage revisions](#how-to-enablemanage-revisions) +- [FAQ](#faq) +- [License](#license) ## Key features - __Lightweight__ @@ -44,8 +47,8 @@ A __lightweight__ & __gdpr compliant__ cookie consent plugin written in plain ja ```bash # CDN links - https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@v2.8.0/dist/cookieconsent.js - https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@v2.8.0/dist/cookieconsent.css + https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@v2.8.1/dist/cookieconsent.js + https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@v2.8.1/dist/cookieconsent.css ``` Thanks to [Till Sanders](https://github.com/tillsanders) for bringing the plugin on npm. @@ -58,14 +61,18 @@ A __lightweight__ & __gdpr compliant__ cookie consent plugin written in plain ja 1. Import the plugin: add a `script` tag pointing to `cookieconsent.js` ```html - + + + + + ``` - Note: replace `` with a valid path! + Note: replace `` and `` with valid paths!
3. Configure and run diff --git a/dist/cookieconsent.js b/dist/cookieconsent.js index 184bf5c9..ce524ec9 100644 --- a/dist/cookieconsent.js +++ b/dist/cookieconsent.js @@ -1,5 +1,5 @@ /* - CookieConsent v3.0.0-beta.1 + CookieConsent v2.8.1 https://www.github.com/orestbida/cookieconsent Author Orest Bida Released under the MIT License diff --git a/src/cookieconsent.js b/src/cookieconsent.js index 471d97e4..9a6d2afc 100644 --- a/src/cookieconsent.js +++ b/src/cookieconsent.js @@ -1,5 +1,5 @@ /*! - * CookieConsent v3.0.0-beta.1 + * CookieConsent v2.8.1 * https://www.github.com/orestbida/cookieconsent * Author Orest Bida * Released under the MIT License From 2834fb237447fc97808d806fb5aeb98ffaa3afd6 Mon Sep 17 00:00:00 2001 From: Orest Bida Date: Wed, 22 Jun 2022 19:01:39 +0200 Subject: [PATCH 10/10] Delete type.d.ts --- type.d.ts | 146 ------------------------------------------------------ 1 file changed, 146 deletions(-) delete mode 100644 type.d.ts diff --git a/type.d.ts b/type.d.ts deleted file mode 100644 index 34d64d88..00000000 --- a/type.d.ts +++ /dev/null @@ -1,146 +0,0 @@ -export {} - -declare global { - type MODE = 'opt-in' | 'opt-out' - - type AUTO_LANGUAGE_ORIGIN = 'browser' | 'document' - - type ModalLayout = 'box' | 'cloud' | 'bar' - - type ModalPosition = 'bottom left' | 'bottom right' | 'bottom center' | 'middle left' | 'middle right' | 'middle center' | 'top left' | 'top right' | 'top center' - - type GUITransition = 'zoom' | 'slide' - - type SettingLayout = 'box' | 'bar' - - type SettingPosition = 'left' | 'right' - - interface SavedCookieContent { - categories: string[] - revision: number - data?: null | Record | string> - rfc_cookie: boolean - consent_date: string - consent_uuid: string - last_consent_update: string - } - - interface GUIOptions { - consent_modal?: { - layout?: ModalLayout - position?: ModalPosition - transition?: GUITransition - swap_buttons?: boolean - }, - settings_modal?: { - layout?: SettingLayout - position?: SettingPosition - transition?: GUITransition - } - } - - interface UserPreferences { - accept_type: string - accepted_categories: string[] - rejected_categories: string[] - } - - type PrimaryButtonRole = 'accept_selected' | 'accept_all' - - type SecondaryButtonRole = 'settings' | 'accept_necessary' - - interface ButtonSetting { - text: string - role: Role - } - - interface ConsentModalLanguageSetting { - title?: string - description?: string - primary_btn?: ButtonSetting - secondary_btn?: ButtonSetting - revision_message?: string - } - - interface ToggleSetting { - value: string - enabled?: boolean - readonly?: boolean - } - - interface BlockSetting { - title: string - description: string - toggle?: ToggleSetting - cookie_table_headers?: Record[] - cookie_table?: Record[] - } - - interface SettingsModalLanguageSetting { - title?: string - save_settings_btn?: string - accept_all_btn?: string - reject_all_btn?: string - blocks?: BlockSetting[] - } - - interface LanguageSetting { - consent_modal?: ConsentModalLanguageSetting - settings_modal?: SettingsModalLanguageSetting - } - - interface UserConfig { - autorun?: boolean - delay?: number - mode?: MODE - cookie_expiration?: number - cookie_necessary_only_expiration?: number - cookie_path?: string - cookie_domain?: string - cookie_same_site?: string - use_rfc_cookie?: boolean - force_consent?: boolean - revision?: number - current_lang?: string - auto_language?: AUTO_LANGUAGE_ORIGIN - autoclear_cookies?: boolean - page_scripts?: boolean - remove_cookie_tables?: boolean - hide_from_bots?: boolean - gui_options?: GUIOptions - onAccept?: (savedCookieContent: SavedCookieContent) => void - onChange?: (cookie: SavedCookieContent, changedCookieCategories: string[]) => void - onFirstAction? :(userPreferences: UserPreferences, cookie: SavedCookieContent) => void - languages?: Record - } - - interface ScriptAttribute { - name: string - value: any - } - - interface CookieConsent { - run(config: UserConfig): void - showSettings(delay: number): void - accept(_categories: string | string[], _exclusions?: string[]): void - hideSettings(): void - hide(): void - updateLanguage(lang: string, force: boolean): boolean - getUserPreferences(): UserPreferences - loadScript(src: string, callback: () => void | typeof onload, attrs?: ScriptAttribute[]): void - updateScripts(): void - show(delay?: number, create_modal?: boolean): void - eraseCookies(_cookies: string | string[], _path?: string, _domain?: string): void - validCookie(cookie_name: string): boolean - allowedCategory(cookie_category: string): boolean - set(field: string, data: Record): boolean - get(field: string, cookie_name?: string): Record - getConfig(field: Field): UserConfig[Field] - } - - function initCookieConsent(root?: HTMLElement): CookieConsent - - interface Window { - initCookieConsent: typeof initCookieConsent - } -}