From 294a50df03a5fdec73e099cce493fde4f215698b Mon Sep 17 00:00:00 2001 From: Phil Ricketts <812139+replete@users.noreply.github.com> Date: Fri, 9 Aug 2024 01:46:58 +0100 Subject: [PATCH] Extend browser support with dialog polyfill --- README.md | 44 ++++++++++++++++------------- dist/biscuitman.css | 14 ++++++--- dist/biscuitman.js | 22 +++++++++++++-- dist/biscuitman.min.css | 2 +- dist/biscuitman.min.js | 2 +- dist/biscuitman.withcss.js | 36 ++++++++++++++++++----- dist/biscuitman.withcss.min.js | 2 +- dist/esm/biscuitman.min.mjs | 2 +- dist/esm/biscuitman.mjs | 22 +++++++++++++-- dist/esm/biscuitman.withcss.min.mjs | 2 +- dist/esm/biscuitman.withcss.mjs | 36 ++++++++++++++++++----- index-esm.html | 4 +-- index.html | 2 +- package.json | 2 +- run.js | 14 ++++----- src/biscuitman.css | 15 +++++++--- src/biscuitman.js | 22 ++++++++++++++- src/biscuitman.mjs | 21 +++++++++++++- 18 files changed, 197 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index 6ecd33b..336c4f4 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ #### [View demo](https://replete.github.io/biscuitman) -100kB+ seemed too heavy for a cookie popup so I wrote this. It's currently < 4kB gz/br, including CSS. It's designed to be as small as possible with an adequate featureset for basic website cookie consent. +100kB+ seemed too heavy for a cookie popup so I wrote this. It's around 4kB gz/br, including CSS. It's designed to be as small as possible with an adequate featureset for basic website cookie consent. - Stores consent in `localStorage`, exposes in `window.Consent` and through custom events fired on `document` - Handles consent granulated by custom sections (e.g. essential, performance, analytics...) @@ -21,16 +21,10 @@ - include optional link in any text - CSS classes on `` element for consents - Progressively enhanced CSS -- Ideal experience browser support (targeted via browserlist string `>= 2%, last 2 years`): - - Chrome/Edge 105+ (should be fine in many earlier versions, TBD) - - Safari 15.4+ - - Firefox 121+ (should be fine in many earlier versions, TBD) - - If JS fails in an old browser, it will probably be fixable by updating `browserlist` in `package.json` then rebuilding - - (Will be tested more definitively with browserstack at some point) - - source styles use CSS Nesting which is explicitly processed out for compatibility +- Dialog polyfill loads as required (see [Browser Support](#browser-support)) - Experimental ESM version included `biscuitman.mjs` (see [ESM demo](https://replete.github.io/biscuitman/index-esm.html)) - Preliminary e2e tests: -![tests](https://github.com/replete/biscuitman/actions/workflows/node.js.yml/badge.svg) +![tests](https://github.com/replete/biscuitman/actions/workflows/node.js.yml/badge.svg) ([failing due to GTM.js bug](https://github.com/replete/biscuitman/issues/4), pass locally) ## How to use [View demo](https://replete.github.io/biscuitman) for a more detailed example @@ -74,6 +68,7 @@ // more: '(Show more)', // Show more button text // noCookies: 'No cookies to display', // Displayed in expanded sections within modal // acceptNonEU: false, // When enabled biscuitman checks browser locale timezone to see if it matches EU, if not it will auto consent + //dialogPolyfillUrl: '//cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.5.6/dialog-polyfill.min.js' // extends browser support, overridable if you want to self-host. Grab the .css too, and host in the same place. message: 'By clicking "Accept All", you agree to the use of cookies for improving browsing, providing personalized ads or content, and analyzing traffic. {link}', // {link} inside any configuration string will be replaced with an link @@ -151,7 +146,7 @@ I've included an ESM version as an alternative packaging format. Longterm it's b ## Theme CSS -It's easy enough to theme the included styles by overriding CSS variables. They are shortened for filsize savings, but straightforward: +It's easy enough to theme the included styles by overriding CSS variables. They are shortened but straightforward: ```css /* hacker mode */ @@ -185,15 +180,22 @@ html.bm-show::after { ## Browser Support -With browserlist, we're targeting `">= 2%, last 2 years"`. This project is tested with BrowserStack. The earliest versions tested working are: +With browserlist, we're targeting `">= 2%, last 2 years"`. The earliest versions tested working are: - Chrome/Edge/Opera: 85+ (released June 2020) - Firefox: 98+ (released March 2022) -- Safari Desktop+iOS: 15.4+ (released March 2022) - - I couldn't easily test 15.0-15.3, 14.1 is broken though +- Safari (inc iOS): 15.4+ (released March 2022) - Samsung Internet: 14+ (released April 2021) -Currently if this is used in a browser that breaks interactivity (e.g. Safari 14.1, released April 2021), the site is unusable. It might be worth catching errors for unsupported browsers and removing the UI altogether for these extreme edge cases of users not updating their browsers. +With `v0.3.19`, a [polyfill for dialog](https://github.com/GoogleChrome/dialog-polyfill) is loaded as necessary, extending the support to include these browsers (tested): + +- Safari (inc iOS): 13.1+ (released March 2020) +- Firefox: 77+ (released June 2020) +- Firefox Android: 79+ (released August 2020) + +If you need to support earlier than these browsers, you will need to start loading polyfills for missing javascript features, starting with `String.prototype.replaceAll`. [Cloudflare's polyfill CDN site](https://cdnjs.cloudflare.com/polyfill) will help you generate a package which will need to load before biscuitman. + +This project is tested with BrowserStack. ## Globals - `biscuitman` – configuration object, must be `window.biscuitman` (`biscuitman.create(options)` for ESM version) @@ -213,10 +215,12 @@ Currently if this is used in a browser that breaks interactivity (e.g. Safari 14 - `bmOpen()` – Opens My Consent Settings modal (you might want to link this on your Privacy policy or footer nav) - example usage: ` Update my consent settings` +The ESM version currently does still use some globals. + ## CSS Classes - `biscuitman` on UI container -- `bm-{sectionName}`, `bm-no-{sectionName}`, `bm-show` on `` +- `bm-{sectionName}`, `bm-no-{sectionName}`, `bm-show` and sometimes `bm-dialog-polyfill` on `` - `--bm-height` CSS variable written to `` ## Events @@ -241,22 +245,22 @@ document.addEventListener('biscuitman:open', (e) => { ## Development -`npm run dev` fires up a browsersync dev server on `https://localhost:3000`. +`npm run dev` fires up a browserSync development server on `https://localhost:3000`. -We need to use `https://` to be able to delete Secure cookies. +We need `https://` active to be able to delete Secure cookies. ### Fix NET::ERR_CERT_AUTHORITY_INVALID error -This isn't a problem for testing the UI, but is a problem for the tests running headless browsers. To fix this: +To prevent invalid certificate warnings, you can generate a local SSL key with `mkcert`: - Install `mkcert` ([Installation instructions](https://github.com/FiloSottile/mkcert#installation)) and then run: -- run `npm run makecerts`, to create `server.crt` and `server.key` for browserSync +- run `npm run makecerts`, to generate `server.crt` and `server.key` for browserSync dev server - if you're using another solution for local SSL certs, generate `server.crt` and `server.key` manually and place them in the root Visiting `https://localhost:3000` should now work without warnings. ### Building -`npm run build` - creates project distributes via `run.js` a custom build script requiring `Node v20` +`npm run build` - creates project distributes via `run.js`, a custom build script requiring `Node v20` ### Tests Jest is set up with puppeteer to run some integration tests. We're using `@swc/jest`'s rust implementation of jest to speed things up. This is only chromium for now, but at some point it would be good to implement browserStack selenium tests to automate browser compatibility checks. diff --git a/dist/biscuitman.css b/dist/biscuitman.css index 3ffa77e..d4c6db4 100644 --- a/dist/biscuitman.css +++ b/dist/biscuitman.css @@ -1,4 +1,4 @@ -/*! biscuitman.js 0.3.18 */ +/*! biscuitman.js 0.3.19 */ .biscuitman { --ui: 0, 0, 0; --tx: #444; @@ -16,7 +16,7 @@ box-shadow: 0 -2px 10px #00000029; } -html.bm-show .biscuitman { +.bm-show .biscuitman { display: block; } @@ -175,7 +175,7 @@ html.bm-show .biscuitman { .biscuitman .bm-dialog > b:after { content: ""; - background: linear-gradient(180deg, var(--bg) 20%, transparent); + background: linear-gradient(180deg, var(--bg) 20%, #fff0); pointer-events: none; z-index: 1; width: 100%; @@ -188,7 +188,7 @@ html.bm-show .biscuitman { .biscuitman .bm-dialog nav:after { content: ""; - background: linear-gradient(0deg, var(--bg) 20%, transparent); + background: linear-gradient(0deg, var(--bg) 20%, #fff0); pointer-events: none; width: 100%; height: 25px; @@ -385,3 +385,9 @@ html.bm-show .biscuitman { .biscuitman label input { opacity: 0; } + +.bm-dialog-polyfill .biscuitman dialog { + position: fixed; + top: 50%; + transform: translateY(-50%); +} diff --git a/dist/biscuitman.js b/dist/biscuitman.js index b4a710e..59ddfd0 100644 --- a/dist/biscuitman.js +++ b/dist/biscuitman.js @@ -1,4 +1,4 @@ -/*! biscuitman.js 0.3.18 */ +/*! biscuitman.js 0.3.19 */ ((d, w, O, h, bm)=>{ const defaults = { key: 'myconsent', @@ -18,7 +18,8 @@ info: '', more: 'Show more', noCookies: 'No cookies to display', - acceptNonEU: false + acceptNonEU: false, + dialogPolyfillUrl: '//cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.5.6/dialog-polyfill.min.js' }; const o = { ...defaults, @@ -82,6 +83,7 @@ `.replaceAll('{link}', `${o.linkText}`); ui.querySelectorAll('button').forEach((b)=>b.addEventListener('click', buttonHandler)); dialog = ui.querySelector('dialog'); + if (!dialog.showModal || !dialog.close) loadDialogPolyfill(); dialog.addEventListener('close', closeModalHandler); dialog.addEventListener('cancel', cancelModalHandler); const moreLink = ui.querySelector('.more'); @@ -235,7 +237,7 @@ }); clearStorages(); insertScripts(); - dialog.close(); + if (dialog.open) dialog.close(); displayUI(false); } function insertScripts() { @@ -312,4 +314,18 @@ }); openModal(); }; + function loadDialogPolyfill() { + // https://github.com/GoogleChrome/dialog-polyfill + h.classList.add('bm-dialog-polyfill'); + const script = d.createElement('script'); + script.src = o.dialogPolyfillUrl; + script.onload = ()=>{ + w.dialogPolyfill.registerDialog(dialog); + }; + d.head.appendChild(script); + const link = d.createElement('link'); + link.rel = 'stylesheet'; + link.href = o.dialogPolyfillUrl.slice(0, -2) + 'css'; + d.head.appendChild(link); + } })(document, window, Object, document.documentElement, 'biscuitman'); diff --git a/dist/biscuitman.min.css b/dist/biscuitman.min.css index 1e75147..927f1e6 100644 --- a/dist/biscuitman.min.css +++ b/dist/biscuitman.min.css @@ -1 +1 @@ -/*! biscuitman.js 0.3.18 */.biscuitman{--ui:0,0,0;--tx:#444;--bg:#fff;--c:#105d89;background:var(--bg);box-sizing:border-box;z-index:3;width:100%;padding:20px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;display:none;position:fixed;bottom:0;box-shadow:0 -2px 10px #00000029}html.bm-show .biscuitman{display:block}.biscuitman *{box-sizing:border-box;color:var(--tx);margin:0;padding:0;font-family:inherit;font-size:16px;line-height:1.4em}.biscuitman:has([open]){transform:translateY(100%)}.biscuitman article{padding:0;position:relative}@media (min-width:770px){.biscuitman article{padding-right:calc(max(300px,30vw) + 20px)}.biscuitman article nav{width:30vw;min-width:300px;position:absolute;bottom:50%;right:0;transform:translateY(50%)}}.biscuitman article p{color:var(--tx);margin:10px 0;font-size:13px}@media (min-width:575px){.biscuitman article p{font-size:14px}}.biscuitman button{background:var(--bg);border:2px solid var(--c);color:var(--c);cursor:pointer;border-radius:3px;margin-top:10px;padding:.8em;font-size:13px;line-height:1em}.biscuitman button[data-id=accept]{background:var(--c);color:var(--bg)!important}.biscuitman button[data-id=close]{color:rgba(var(--ui),.5);opacity:.6;-webkit-user-select:none;user-select:none;z-index:2;background:0 0;border:none;outline:none;padding:10px;font-size:24px;line-height:1em;position:absolute;top:0;right:10px}.biscuitman button[disabled]{display:none}.biscuitman button:hover{opacity:.8}@media (min-width:576px){.biscuitman nav{flex-direction:row-reverse;gap:10px;width:100%;display:flex}.biscuitman nav button{flex-grow:1;margin-bottom:0}}@media (max-width:575px){.biscuitman nav{flex-direction:column;flex-grow:1;display:flex}}.biscuitman dialog{background:var(--bg);border:0;width:100%;max-width:100%;height:100%;max-height:100%}@media (min-width:576px){.biscuitman dialog{border-radius:10px;width:90vw;max-width:860px;max-height:80vh;margin:auto;box-shadow:0 0 8px #0000004d}}@media (min-width:576px) and (min-height:1134px){.biscuitman dialog{max-height:950px}}.biscuitman dialog nav{justify-self:flex-end;position:relative}.biscuitman .bm-dialog{flex-direction:column;height:100%;padding:20px;display:flex}.biscuitman .bm-dialog b{padding-bottom:8px;position:relative}.biscuitman .bm-dialog>b:after{content:"";background:linear-gradient(180deg,var(--bg)20%,transparent);pointer-events:none;z-index:1;width:100%;height:25px;margin-bottom:-24px;position:absolute;bottom:0;left:0}.biscuitman .bm-dialog nav:after{content:"";background:linear-gradient(0deg,var(--bg)20%,transparent);pointer-events:none;width:100%;height:25px;position:absolute;top:-24px;left:0}.biscuitman .bm-sections{scrollbar-color:rgba(var(--ui),.2)var(--bg);flex-shrink:1;height:100%;padding:15px 0;position:relative;overflow-y:scroll}@media (min-width:576px){.biscuitman .bm-sections{margin-right:-18px;padding-right:4px}}.biscuitman .bm-sections>p{padding-right:30px;font-size:13px;line-height:18px}@media (min-width:576px){.biscuitman .bm-sections>p{font-size:14px}}.biscuitman .bm-sections>p span{font-size:inherit;padding-bottom:5px;display:inline-block}.biscuitman .bm-sections>p .more~span{display:none}.biscuitman a{font-size:inherit;color:var(--c);cursor:pointer;text-decoration:none;display:inline-block}.biscuitman a:hover{text-decoration:underline}.biscuitman section{margin-bottom:10px;position:relative}.biscuitman section:first-of-type{margin-top:10px}.biscuitman details{border:1px solid rgba(var(--ui),.2);border-radius:5px;padding:10px;list-style:none;box-shadow:0 2px 4px #0000001a}.biscuitman details[open] summary b:after{margin:-3px 0 0 -2px;transform:rotate(45deg)scale(.3)}.biscuitman summary{cursor:pointer;flex-direction:column;width:100%;padding:5px 80px 10px 10px;list-style:none;display:flex;position:relative}.biscuitman summary b{margin-bottom:3px}.biscuitman summary b:after{content:"";border:5px solid rgba(var(--ui),.4);border-top-color:#0000;border-left-color:#0000;border-radius:2px;width:1em;height:1em;margin:-2px 0 0 -4px;display:block;transform:rotate(-45deg)scale(.3)}.biscuitman summary p{color:var(--tx);font-size:14px}.biscuitman summary>*{display:inline-flex}.biscuitman summary::marker{display:none}.biscuitman summary::-webkit-details-marker{display:none}.biscuitman dl{background:rgba(var(--ui),.08);margin:10px;padding:10px;display:flex}.biscuitman dl dt,.biscuitman dl dd{color:var(--tx);font-size:12px}.biscuitman dl dt{min-width:120px;padding-right:30px;font-weight:700}.biscuitman label{--height:1.2em;--width:2.3em;--gap:2px;height:var(--height);width:var(--width);background-color:rgba(var(--ui),.3);border-radius:var(--height);margin-top:-2px;display:block;position:absolute;top:50%;right:20px;transform:translateY(-50%);font-size:20px!important}.biscuitman label:before{content:"";background:var(--bg);height:calc(var(--height) - calc(var(--gap)*2));width:calc(var(--height) - calc(var(--gap)*2));height:var(--height);width:var(--height);left:var(--gap);transform-origin:50%;border-radius:100%;display:block;position:absolute;top:50%;left:0;transform:translateY(-50%)scale(.8)}.biscuitman label.checked{background-color:var(--c)}.biscuitman label.checked:before{left:auto;right:0}.biscuitman label:has(:focus-visible){outline:auto highlight}.biscuitman label.disabled.checked{opacity:.5}.biscuitman label input{opacity:0} \ No newline at end of file +/*! biscuitman.js 0.3.19 */.biscuitman{--ui:0,0,0;--tx:#444;--bg:#fff;--c:#105d89;background:var(--bg);box-sizing:border-box;z-index:3;width:100%;padding:20px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;display:none;position:fixed;bottom:0;box-shadow:0 -2px 10px #00000029}.bm-show .biscuitman{display:block}.biscuitman *{box-sizing:border-box;color:var(--tx);margin:0;padding:0;font-family:inherit;font-size:16px;line-height:1.4em}.biscuitman:has([open]){transform:translateY(100%)}.biscuitman article{padding:0;position:relative}@media (min-width:770px){.biscuitman article{padding-right:calc(max(300px,30vw) + 20px)}.biscuitman article nav{width:30vw;min-width:300px;position:absolute;bottom:50%;right:0;transform:translateY(50%)}}.biscuitman article p{color:var(--tx);margin:10px 0;font-size:13px}@media (min-width:575px){.biscuitman article p{font-size:14px}}.biscuitman button{background:var(--bg);border:2px solid var(--c);color:var(--c);cursor:pointer;border-radius:3px;margin-top:10px;padding:.8em;font-size:13px;line-height:1em}.biscuitman button[data-id=accept]{background:var(--c);color:var(--bg)!important}.biscuitman button[data-id=close]{color:rgba(var(--ui),.5);opacity:.6;-webkit-user-select:none;user-select:none;z-index:2;background:0 0;border:none;outline:none;padding:10px;font-size:24px;line-height:1em;position:absolute;top:0;right:10px}.biscuitman button[disabled]{display:none}.biscuitman button:hover{opacity:.8}@media (min-width:576px){.biscuitman nav{flex-direction:row-reverse;gap:10px;width:100%;display:flex}.biscuitman nav button{flex-grow:1;margin-bottom:0}}@media (max-width:575px){.biscuitman nav{flex-direction:column;flex-grow:1;display:flex}}.biscuitman dialog{background:var(--bg);border:0;width:100%;max-width:100%;height:100%;max-height:100%}@media (min-width:576px){.biscuitman dialog{border-radius:10px;width:90vw;max-width:860px;max-height:80vh;margin:auto;box-shadow:0 0 8px #0000004d}}@media (min-width:576px) and (min-height:1134px){.biscuitman dialog{max-height:950px}}.biscuitman dialog nav{justify-self:flex-end;position:relative}.biscuitman .bm-dialog{flex-direction:column;height:100%;padding:20px;display:flex}.biscuitman .bm-dialog b{padding-bottom:8px;position:relative}.biscuitman .bm-dialog>b:after{content:"";background:linear-gradient(180deg,var(--bg)20%,#fff0);pointer-events:none;z-index:1;width:100%;height:25px;margin-bottom:-24px;position:absolute;bottom:0;left:0}.biscuitman .bm-dialog nav:after{content:"";background:linear-gradient(0deg,var(--bg)20%,#fff0);pointer-events:none;width:100%;height:25px;position:absolute;top:-24px;left:0}.biscuitman .bm-sections{scrollbar-color:rgba(var(--ui),.2)var(--bg);flex-shrink:1;height:100%;padding:15px 0;position:relative;overflow-y:scroll}@media (min-width:576px){.biscuitman .bm-sections{margin-right:-18px;padding-right:4px}}.biscuitman .bm-sections>p{padding-right:30px;font-size:13px;line-height:18px}@media (min-width:576px){.biscuitman .bm-sections>p{font-size:14px}}.biscuitman .bm-sections>p span{font-size:inherit;padding-bottom:5px;display:inline-block}.biscuitman .bm-sections>p .more~span{display:none}.biscuitman a{font-size:inherit;color:var(--c);cursor:pointer;text-decoration:none;display:inline-block}.biscuitman a:hover{text-decoration:underline}.biscuitman section{margin-bottom:10px;position:relative}.biscuitman section:first-of-type{margin-top:10px}.biscuitman details{border:1px solid rgba(var(--ui),.2);border-radius:5px;padding:10px;list-style:none;box-shadow:0 2px 4px #0000001a}.biscuitman details[open] summary b:after{margin:-3px 0 0 -2px;transform:rotate(45deg)scale(.3)}.biscuitman summary{cursor:pointer;flex-direction:column;width:100%;padding:5px 80px 10px 10px;list-style:none;display:flex;position:relative}.biscuitman summary b{margin-bottom:3px}.biscuitman summary b:after{content:"";border:5px solid rgba(var(--ui),.4);border-top-color:#0000;border-left-color:#0000;border-radius:2px;width:1em;height:1em;margin:-2px 0 0 -4px;display:block;transform:rotate(-45deg)scale(.3)}.biscuitman summary p{color:var(--tx);font-size:14px}.biscuitman summary>*{display:inline-flex}.biscuitman summary::marker{display:none}.biscuitman summary::-webkit-details-marker{display:none}.biscuitman dl{background:rgba(var(--ui),.08);margin:10px;padding:10px;display:flex}.biscuitman dl dt,.biscuitman dl dd{color:var(--tx);font-size:12px}.biscuitman dl dt{min-width:120px;padding-right:30px;font-weight:700}.biscuitman label{--height:1.2em;--width:2.3em;--gap:2px;height:var(--height);width:var(--width);background-color:rgba(var(--ui),.3);border-radius:var(--height);margin-top:-2px;display:block;position:absolute;top:50%;right:20px;transform:translateY(-50%);font-size:20px!important}.biscuitman label:before{content:"";background:var(--bg);height:calc(var(--height) - calc(var(--gap)*2));width:calc(var(--height) - calc(var(--gap)*2));height:var(--height);width:var(--height);left:var(--gap);transform-origin:50%;border-radius:100%;display:block;position:absolute;top:50%;left:0;transform:translateY(-50%)scale(.8)}.biscuitman label.checked{background-color:var(--c)}.biscuitman label.checked:before{left:auto;right:0}.biscuitman label:has(:focus-visible){outline:auto highlight}.biscuitman label.disabled.checked{opacity:.5}.biscuitman label input{opacity:0}.bm-dialog-polyfill .biscuitman dialog{position:fixed;top:50%;transform:translateY(-50%)} \ No newline at end of file diff --git a/dist/biscuitman.min.js b/dist/biscuitman.min.js index 6100e80..b1c495f 100644 --- a/dist/biscuitman.min.js +++ b/dist/biscuitman.min.js @@ -1 +1 @@ -/*! biscuitman.js 0.3.18 */((e,t,o,a,n)=>{let s;let i={key:"myconsent",global:"Consent",force:!1,enableMore:!0,sections:["essential"],title:"Your privacy matters",message:"We use cookies",settings:"Settings",reject:"Reject All",accept:"Accept All",save:"Save My Settings",settingsTitle:"My Consent Settings",info:"",more:"Show more",noCookies:"No cookies to display",acceptNonEU:!1,...t.biscuitman},c=e.createElement("div"),l=()=>{a.style.setProperty("--bm-height",`${c.offsetHeight}px`)},r=e=>{a.classList.toggle("bm-show",e),l()},d=()=>{let{consentTime:e,...t}=f();for(let[n,s]of(e||(t=o.fromEntries(i.sections.slice(1).map(e=>[e,!1]))),o.entries(t)))a.classList.toggle(`bm-${n}`,s),a.classList.toggle(`bm-no-${n}`,!s)};function m(e){let t=e.target.dataset.id;switch($("button",{id:t}),t){case"accept":E(!0);break;case"close":s.close();break;case"settings":b();break;case"save":E();break;case"reject":E(!1)}}function p(){$("close")}function u(e){i.force&&e.preventDefault()}function b(){$("open"),s.showModal()}function $(t,o){let a=`${n}:${t}`,s={...void 0!==o&&o,time:+new Date};e.dispatchEvent(new CustomEvent(a,s)),console.debug(a,s)}let f=()=>t[i.global]||{};function g(e){t[i.global]=e,d()}function v(e,t){for(let o in e)e[o]&&!1===t[o]&&$("revoke",{section:o})}function k(){try{return JSON.parse(localStorage.getItem(i.key))}catch(e){return console.error(e),localStorage.removeItem(i.key),{}}}function h(){let t=o.fromEntries(o.entries(localStorage)),a=o.fromEntries(e.cookie.split("; ").map(e=>e.split("="))),{consentTime:n,...s}=k()||i.sections.slice(1).reduce((e,t)=>(e[t]=!1,{consentTime:void 0,...e}),{});for(let[n,c]of o.entries(s)){if(c)continue;let s=o.keys(i[`${n}Cookies`]||{});for(let n of(s.filter(e=>e.endsWith("*")).map(e=>{o.keys({...a,...t}).map(t=>{t.startsWith(e.slice(0,-1))&&s.push(t)})}),s)){if(a[n]){let t=`${n}=;expires=Thu, 01 Jan 1970 00:00:01 UTC;path=/;`;e.cookie=t,e.cookie=`${t}domain=${location.hostname};`,e.cookie=`${t}domain=.${location.hostname};`,$("delete",{cookie:n})}t[n]&&(localStorage.removeItem(n),$("delete",{localStorage:n}))}}}function E(e){let t=void 0===e,o={consentTime:+new Date};i.sections.forEach(a=>{if("essential"===a)return!1;let n=c.querySelector(`[data-s=${a}]`),s=t?n.checked:e;o[a]=s,t||(n.checked=e)}),v(f(),o),g(o),localStorage.setItem(i.key,JSON.stringify(o)),$("save",{data:o}),h(),y(),s.close(),r(!1)}function y(){e.querySelectorAll("script[data-consent]").forEach(t=>{if(!f()[t.dataset.consent])return!1;let o=e.createElement("script");for(let{name:e,value:a}of t.attributes)e.startsWith("data-")||"type"===e||o.setAttribute(e,a);o.setAttribute("type",t.dataset.type||"text/javascript"),t.src||(o.textContent=t.textContent),t.parentNode.replaceChild(o,t),$("inject",{el:t,...t.id&&{id:t.id}}),t.src&&""!==t.textContent.trim()&&o.addEventListener("load",()=>{let a=e.createElement("script");a.textContent=t.textContent,t.id&&(a.id=t.id+"-after"),o.insertAdjacentElement("afterend",a),$("inject",{el:a,parent:t,...a.id&&{id:a.id}})})})}g(k()||{});let T=Intl.DateTimeFormat().resolvedOptions().timeZone,S=/^(GMT|UTC)$/.test(T)||/(Europe|BST|CEST|CET|EET|IST|WEST|WET|GMT-1|GMT-2|UTC+1|UTC+2|UTC+3)/.test(T);i.acceptNonEU&&!S&&(E(!0),r(!1)),function(){c.classList.add(n),c.innerHTML=`
${i.title}

${i.message}

${i.settingsTitle}

${i.message}

${i.info.split("\n").map((e,t,o)=>`${e}${o.length>1&&i.enableMore&&0==t?`${i.more}`:""}`).join("")}

${i.sections.map(e=>{let t=f()[e],a="essential"===e,s=a?"disabled":"",c=a?"checked":"";void 0!==t&&(c=t?"checked":"");let l=i[`${e}Cookies`];return`
${i[`${e}Title`]}

${i[`${e}Message`]}

${l?o.entries(l).map(e=>{let[t,o]=e;return`
${t}
${o}
`}).join(""):`
${i.noCookies}
`}
`}).join("")}
`.replaceAll("{link}",`${i.linkText}`),c.querySelectorAll("button").forEach(e=>e.addEventListener("click",m)),(s=c.querySelector("dialog")).addEventListener("close",p),s.addEventListener("cancel",u);let a=c.querySelector(".more");a&&a.addEventListener("click",a.remove),c.querySelectorAll("[data-s]").forEach(e=>e.addEventListener("change",t=>{e.parentElement.classList.toggle("checked",t.target.checked)})),e.body.appendChild(c),t.addEventListener("resize",l)}(),h(),t[i.global].consentTime?(r(!1),y()):(r(!0),i.force&&b()),t.bmInvalidate=()=>{$("invalidate",{data:f()}),v({}),E(!1),g({}),localStorage.removeItem(i.key),r(!0)},t.bmUpdate=()=>{$("update",{data:f()}),b()}})(document,window,Object,document.documentElement,"biscuitman"); \ No newline at end of file +/*! biscuitman.js 0.3.19 */((e,t,o,a,i)=>{let n;let l={key:"myconsent",global:"Consent",force:!1,enableMore:!0,sections:["essential"],title:"Your privacy matters",message:"We use cookies",settings:"Settings",reject:"Reject All",accept:"Accept All",save:"Save My Settings",settingsTitle:"My Consent Settings",info:"",more:"Show more",noCookies:"No cookies to display",acceptNonEU:!1,dialogPolyfillUrl:"//cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.5.6/dialog-polyfill.min.js",...t.biscuitman},s=e.createElement("div"),c=()=>{a.style.setProperty("--bm-height",`${s.offsetHeight}px`)},r=e=>{a.classList.toggle("bm-show",e),c()},d=()=>{let{consentTime:e,...t}=g();for(let[i,n]of(e||(t=o.fromEntries(l.sections.slice(1).map(e=>[e,!1]))),o.entries(t)))a.classList.toggle(`bm-${i}`,n),a.classList.toggle(`bm-no-${i}`,!n)};function p(e){let t=e.target.dataset.id;switch(b("button",{id:t}),t){case"accept":k(!0);break;case"close":n.close();break;case"settings":f();break;case"save":k();break;case"reject":k(!1)}}function m(){b("close")}function u(e){l.force&&e.preventDefault()}function f(){b("open"),n.showModal()}function b(t,o){let a=`${i}:${t}`,n={...void 0!==o&&o,time:+new Date};e.dispatchEvent(new CustomEvent(a,n)),console.debug(a,n)}let g=()=>t[l.global]||{};function $(e){t[l.global]=e,d()}function h(e,t){for(let o in e)e[o]&&!1===t[o]&&b("revoke",{section:o})}function v(){try{return JSON.parse(localStorage.getItem(l.key))}catch(e){return console.error(e),localStorage.removeItem(l.key),{}}}function y(){let t=o.fromEntries(o.entries(localStorage)),a=o.fromEntries(e.cookie.split("; ").map(e=>e.split("="))),{consentTime:i,...n}=v()||l.sections.slice(1).reduce((e,t)=>(e[t]=!1,{consentTime:void 0,...e}),{});for(let[i,s]of o.entries(n)){if(s)continue;let n=o.keys(l[`${i}Cookies`]||{});for(let i of(n.filter(e=>e.endsWith("*")).map(e=>{o.keys({...a,...t}).map(t=>{t.startsWith(e.slice(0,-1))&&n.push(t)})}),n)){if(a[i]){let t=`${i}=;expires=Thu, 01 Jan 1970 00:00:01 UTC;path=/;`;e.cookie=t,e.cookie=`${t}domain=${location.hostname};`,e.cookie=`${t}domain=.${location.hostname};`,b("delete",{cookie:i})}t[i]&&(localStorage.removeItem(i),b("delete",{localStorage:i}))}}}function k(e){let t=void 0===e,o={consentTime:+new Date};l.sections.forEach(a=>{if("essential"===a)return!1;let i=s.querySelector(`[data-s=${a}]`),n=t?i.checked:e;o[a]=n,t||(i.checked=e)}),h(g(),o),$(o),localStorage.setItem(l.key,JSON.stringify(o)),b("save",{data:o}),y(),E(),n.open&&n.close(),r(!1)}function E(){e.querySelectorAll("script[data-consent]").forEach(t=>{if(!g()[t.dataset.consent])return!1;let o=e.createElement("script");for(let{name:e,value:a}of t.attributes)e.startsWith("data-")||"type"===e||o.setAttribute(e,a);o.setAttribute("type",t.dataset.type||"text/javascript"),t.src||(o.textContent=t.textContent),t.parentNode.replaceChild(o,t),b("inject",{el:t,...t.id&&{id:t.id}}),t.src&&""!==t.textContent.trim()&&o.addEventListener("load",()=>{let a=e.createElement("script");a.textContent=t.textContent,t.id&&(a.id=t.id+"-after"),o.insertAdjacentElement("afterend",a),b("inject",{el:a,parent:t,...a.id&&{id:a.id}})})})}$(v()||{});let T=Intl.DateTimeFormat().resolvedOptions().timeZone,S=/^(GMT|UTC)$/.test(T)||/(Europe|BST|CEST|CET|EET|IST|WEST|WET|GMT-1|GMT-2|UTC+1|UTC+2|UTC+3)/.test(T);l.acceptNonEU&&!S&&(k(!0),r(!1)),function(){s.classList.add(i),s.innerHTML=`
${l.title}

${l.message}

${l.settingsTitle}

${l.message}

${l.info.split("\n").map((e,t,o)=>`${e}${o.length>1&&l.enableMore&&0==t?`${l.more}`:""}`).join("")}

${l.sections.map(e=>{let t=g()[e],a="essential"===e,n=a?"disabled":"",s=a?"checked":"";void 0!==t&&(s=t?"checked":"");let c=l[`${e}Cookies`];return`
${l[`${e}Title`]}

${l[`${e}Message`]}

${c?o.entries(c).map(e=>{let[t,o]=e;return`
${t}
${o}
`}).join(""):`
${l.noCookies}
`}
`}).join("")}
`.replaceAll("{link}",`${l.linkText}`),s.querySelectorAll("button").forEach(e=>e.addEventListener("click",p)),(n=s.querySelector("dialog")).showModal&&n.close||function(){a.classList.add("bm-dialog-polyfill");let o=e.createElement("script");o.src=l.dialogPolyfillUrl,o.onload=()=>{t.dialogPolyfill.registerDialog(n)},e.head.appendChild(o);let i=e.createElement("link");i.rel="stylesheet",i.href=l.dialogPolyfillUrl.slice(0,-2)+"css",e.head.appendChild(i)}(),n.addEventListener("close",m),n.addEventListener("cancel",u);let r=s.querySelector(".more");r&&r.addEventListener("click",r.remove),s.querySelectorAll("[data-s]").forEach(e=>e.addEventListener("change",t=>{e.parentElement.classList.toggle("checked",t.target.checked)})),e.body.appendChild(s),t.addEventListener("resize",c)}(),y(),t[l.global].consentTime?(r(!1),E()):(r(!0),l.force&&f()),t.bmInvalidate=()=>{b("invalidate",{data:g()}),h({}),k(!1),$({}),localStorage.removeItem(l.key),r(!0)},t.bmUpdate=()=>{b("update",{data:g()}),f()}})(document,window,Object,document.documentElement,"biscuitman"); \ No newline at end of file diff --git a/dist/biscuitman.withcss.js b/dist/biscuitman.withcss.js index c80b01e..5e9ffd3 100644 --- a/dist/biscuitman.withcss.js +++ b/dist/biscuitman.withcss.js @@ -1,4 +1,4 @@ -/*! biscuitman.js 0.3.18 */ +/*! biscuitman.js 0.3.19 */ ((d, w, O, h, bm)=>{ const defaults = { key: 'myconsent', @@ -18,7 +18,8 @@ info: '', more: 'Show more', noCookies: 'No cookies to display', - acceptNonEU: false + acceptNonEU: false, + dialogPolyfillUrl: '//cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.5.6/dialog-polyfill.min.js' }; const o = { ...defaults, @@ -82,6 +83,7 @@ `.replaceAll('{link}', `${o.linkText}`); ui.querySelectorAll('button').forEach((b)=>b.addEventListener('click', buttonHandler)); dialog = ui.querySelector('dialog'); + if (!dialog.showModal || !dialog.close) loadDialogPolyfill(); dialog.addEventListener('close', closeModalHandler); dialog.addEventListener('cancel', cancelModalHandler); const moreLink = ui.querySelector('.more'); @@ -235,7 +237,7 @@ }); clearStorages(); insertScripts(); - dialog.close(); + if (dialog.open) dialog.close(); displayUI(false); } function insertScripts() { @@ -312,11 +314,25 @@ }); openModal(); }; + function loadDialogPolyfill() { + // https://github.com/GoogleChrome/dialog-polyfill + h.classList.add('bm-dialog-polyfill'); + const script = d.createElement('script'); + script.src = o.dialogPolyfillUrl; + script.onload = ()=>{ + w.dialogPolyfill.registerDialog(dialog); + }; + d.head.appendChild(script); + const link = d.createElement('link'); + link.rel = 'stylesheet'; + link.href = o.dialogPolyfillUrl.slice(0, -2) + 'css'; + d.head.appendChild(link); + } })(document, window, Object, document.documentElement, 'biscuitman'); ; ((d)=>{ let css=d.createElement('style'); - css.textContent=`/*! biscuitman.js 0.3.18 */ + css.textContent=`/*! biscuitman.js 0.3.19 */ .biscuitman { --ui: 0, 0, 0; --tx: #444; @@ -334,7 +350,7 @@ box-shadow: 0 -2px 10px #00000029; } -html.bm-show .biscuitman { +.bm-show .biscuitman { display: block; } @@ -493,7 +509,7 @@ html.bm-show .biscuitman { .biscuitman .bm-dialog > b:after { content: ""; - background: linear-gradient(180deg, var(--bg) 20%, transparent); + background: linear-gradient(180deg, var(--bg) 20%, #fff0); pointer-events: none; z-index: 1; width: 100%; @@ -506,7 +522,7 @@ html.bm-show .biscuitman { .biscuitman .bm-dialog nav:after { content: ""; - background: linear-gradient(0deg, var(--bg) 20%, transparent); + background: linear-gradient(0deg, var(--bg) 20%, #fff0); pointer-events: none; width: 100%; height: 25px; @@ -703,6 +719,12 @@ html.bm-show .biscuitman { .biscuitman label input { opacity: 0; } + +.bm-dialog-polyfill .biscuitman dialog { + position: fixed; + top: 50%; + transform: translateY(-50%); +} `; d.head.appendChild(css) })(document); \ No newline at end of file diff --git a/dist/biscuitman.withcss.min.js b/dist/biscuitman.withcss.min.js index 62a14ea..d906e70 100644 --- a/dist/biscuitman.withcss.min.js +++ b/dist/biscuitman.withcss.min.js @@ -1 +1 @@ -/*! biscuitman.js 0.3.18 */((e,t,o,a,n)=>{let s;let i={key:"myconsent",global:"Consent",force:!1,enableMore:!0,sections:["essential"],title:"Your privacy matters",message:"We use cookies",settings:"Settings",reject:"Reject All",accept:"Accept All",save:"Save My Settings",settingsTitle:"My Consent Settings",info:"",more:"Show more",noCookies:"No cookies to display",acceptNonEU:!1,...t.biscuitman},c=e.createElement("div"),l=()=>{a.style.setProperty("--bm-height",`${c.offsetHeight}px`)},r=e=>{a.classList.toggle("bm-show",e),l()},d=()=>{let{consentTime:e,...t}=f();for(let[n,s]of(e||(t=o.fromEntries(i.sections.slice(1).map(e=>[e,!1]))),o.entries(t)))a.classList.toggle(`bm-${n}`,s),a.classList.toggle(`bm-no-${n}`,!s)};function m(e){let t=e.target.dataset.id;switch($("button",{id:t}),t){case"accept":E(!0);break;case"close":s.close();break;case"settings":b();break;case"save":E();break;case"reject":E(!1)}}function p(){$("close")}function u(e){i.force&&e.preventDefault()}function b(){$("open"),s.showModal()}function $(t,o){let a=`${n}:${t}`,s={...void 0!==o&&o,time:+new Date};e.dispatchEvent(new CustomEvent(a,s)),console.debug(a,s)}let f=()=>t[i.global]||{};function g(e){t[i.global]=e,d()}function v(e,t){for(let o in e)e[o]&&!1===t[o]&&$("revoke",{section:o})}function k(){try{return JSON.parse(localStorage.getItem(i.key))}catch(e){return console.error(e),localStorage.removeItem(i.key),{}}}function h(){let t=o.fromEntries(o.entries(localStorage)),a=o.fromEntries(e.cookie.split("; ").map(e=>e.split("="))),{consentTime:n,...s}=k()||i.sections.slice(1).reduce((e,t)=>(e[t]=!1,{consentTime:void 0,...e}),{});for(let[n,c]of o.entries(s)){if(c)continue;let s=o.keys(i[`${n}Cookies`]||{});for(let n of(s.filter(e=>e.endsWith("*")).map(e=>{o.keys({...a,...t}).map(t=>{t.startsWith(e.slice(0,-1))&&s.push(t)})}),s)){if(a[n]){let t=`${n}=;expires=Thu, 01 Jan 1970 00:00:01 UTC;path=/;`;e.cookie=t,e.cookie=`${t}domain=${location.hostname};`,e.cookie=`${t}domain=.${location.hostname};`,$("delete",{cookie:n})}t[n]&&(localStorage.removeItem(n),$("delete",{localStorage:n}))}}}function E(e){let t=void 0===e,o={consentTime:+new Date};i.sections.forEach(a=>{if("essential"===a)return!1;let n=c.querySelector(`[data-s=${a}]`),s=t?n.checked:e;o[a]=s,t||(n.checked=e)}),v(f(),o),g(o),localStorage.setItem(i.key,JSON.stringify(o)),$("save",{data:o}),h(),y(),s.close(),r(!1)}function y(){e.querySelectorAll("script[data-consent]").forEach(t=>{if(!f()[t.dataset.consent])return!1;let o=e.createElement("script");for(let{name:e,value:a}of t.attributes)e.startsWith("data-")||"type"===e||o.setAttribute(e,a);o.setAttribute("type",t.dataset.type||"text/javascript"),t.src||(o.textContent=t.textContent),t.parentNode.replaceChild(o,t),$("inject",{el:t,...t.id&&{id:t.id}}),t.src&&""!==t.textContent.trim()&&o.addEventListener("load",()=>{let a=e.createElement("script");a.textContent=t.textContent,t.id&&(a.id=t.id+"-after"),o.insertAdjacentElement("afterend",a),$("inject",{el:a,parent:t,...a.id&&{id:a.id}})})})}g(k()||{});let T=Intl.DateTimeFormat().resolvedOptions().timeZone,S=/^(GMT|UTC)$/.test(T)||/(Europe|BST|CEST|CET|EET|IST|WEST|WET|GMT-1|GMT-2|UTC+1|UTC+2|UTC+3)/.test(T);i.acceptNonEU&&!S&&(E(!0),r(!1)),function(){c.classList.add(n),c.innerHTML=`
${i.title}

${i.message}

${i.settingsTitle}

${i.message}

${i.info.split("\n").map((e,t,o)=>`${e}${o.length>1&&i.enableMore&&0==t?`${i.more}`:""}`).join("")}

${i.sections.map(e=>{let t=f()[e],a="essential"===e,s=a?"disabled":"",c=a?"checked":"";void 0!==t&&(c=t?"checked":"");let l=i[`${e}Cookies`];return`
${i[`${e}Title`]}

${i[`${e}Message`]}

${l?o.entries(l).map(e=>{let[t,o]=e;return`
${t}
${o}
`}).join(""):`
${i.noCookies}
`}
`}).join("")}
`.replaceAll("{link}",`${i.linkText}`),c.querySelectorAll("button").forEach(e=>e.addEventListener("click",m)),(s=c.querySelector("dialog")).addEventListener("close",p),s.addEventListener("cancel",u);let a=c.querySelector(".more");a&&a.addEventListener("click",a.remove),c.querySelectorAll("[data-s]").forEach(e=>e.addEventListener("change",t=>{e.parentElement.classList.toggle("checked",t.target.checked)})),e.body.appendChild(c),t.addEventListener("resize",l)}(),h(),t[i.global].consentTime?(r(!1),y()):(r(!0),i.force&&b()),t.bmInvalidate=()=>{$("invalidate",{data:f()}),v({}),E(!1),g({}),localStorage.removeItem(i.key),r(!0)},t.bmUpdate=()=>{$("update",{data:f()}),b()}})(document,window,Object,document.documentElement,"biscuitman");;((d)=>{let c=d.createElement('style');c.textContent=`/*! biscuitman.js 0.3.18 */.biscuitman{--ui:0,0,0;--tx:#444;--bg:#fff;--c:#105d89;background:var(--bg);box-sizing:border-box;z-index:3;width:100%;padding:20px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;display:none;position:fixed;bottom:0;box-shadow:0 -2px 10px #00000029}html.bm-show .biscuitman{display:block}.biscuitman *{box-sizing:border-box;color:var(--tx);margin:0;padding:0;font-family:inherit;font-size:16px;line-height:1.4em}.biscuitman:has([open]){transform:translateY(100%)}.biscuitman article{padding:0;position:relative}@media (min-width:770px){.biscuitman article{padding-right:calc(max(300px,30vw) + 20px)}.biscuitman article nav{width:30vw;min-width:300px;position:absolute;bottom:50%;right:0;transform:translateY(50%)}}.biscuitman article p{color:var(--tx);margin:10px 0;font-size:13px}@media (min-width:575px){.biscuitman article p{font-size:14px}}.biscuitman button{background:var(--bg);border:2px solid var(--c);color:var(--c);cursor:pointer;border-radius:3px;margin-top:10px;padding:.8em;font-size:13px;line-height:1em}.biscuitman button[data-id=accept]{background:var(--c);color:var(--bg)!important}.biscuitman button[data-id=close]{color:rgba(var(--ui),.5);opacity:.6;-webkit-user-select:none;user-select:none;z-index:2;background:0 0;border:none;outline:none;padding:10px;font-size:24px;line-height:1em;position:absolute;top:0;right:10px}.biscuitman button[disabled]{display:none}.biscuitman button:hover{opacity:.8}@media (min-width:576px){.biscuitman nav{flex-direction:row-reverse;gap:10px;width:100%;display:flex}.biscuitman nav button{flex-grow:1;margin-bottom:0}}@media (max-width:575px){.biscuitman nav{flex-direction:column;flex-grow:1;display:flex}}.biscuitman dialog{background:var(--bg);border:0;width:100%;max-width:100%;height:100%;max-height:100%}@media (min-width:576px){.biscuitman dialog{border-radius:10px;width:90vw;max-width:860px;max-height:80vh;margin:auto;box-shadow:0 0 8px #0000004d}}@media (min-width:576px) and (min-height:1134px){.biscuitman dialog{max-height:950px}}.biscuitman dialog nav{justify-self:flex-end;position:relative}.biscuitman .bm-dialog{flex-direction:column;height:100%;padding:20px;display:flex}.biscuitman .bm-dialog b{padding-bottom:8px;position:relative}.biscuitman .bm-dialog>b:after{content:"";background:linear-gradient(180deg,var(--bg)20%,transparent);pointer-events:none;z-index:1;width:100%;height:25px;margin-bottom:-24px;position:absolute;bottom:0;left:0}.biscuitman .bm-dialog nav:after{content:"";background:linear-gradient(0deg,var(--bg)20%,transparent);pointer-events:none;width:100%;height:25px;position:absolute;top:-24px;left:0}.biscuitman .bm-sections{scrollbar-color:rgba(var(--ui),.2)var(--bg);flex-shrink:1;height:100%;padding:15px 0;position:relative;overflow-y:scroll}@media (min-width:576px){.biscuitman .bm-sections{margin-right:-18px;padding-right:4px}}.biscuitman .bm-sections>p{padding-right:30px;font-size:13px;line-height:18px}@media (min-width:576px){.biscuitman .bm-sections>p{font-size:14px}}.biscuitman .bm-sections>p span{font-size:inherit;padding-bottom:5px;display:inline-block}.biscuitman .bm-sections>p .more~span{display:none}.biscuitman a{font-size:inherit;color:var(--c);cursor:pointer;text-decoration:none;display:inline-block}.biscuitman a:hover{text-decoration:underline}.biscuitman section{margin-bottom:10px;position:relative}.biscuitman section:first-of-type{margin-top:10px}.biscuitman details{border:1px solid rgba(var(--ui),.2);border-radius:5px;padding:10px;list-style:none;box-shadow:0 2px 4px #0000001a}.biscuitman details[open] summary b:after{margin:-3px 0 0 -2px;transform:rotate(45deg)scale(.3)}.biscuitman summary{cursor:pointer;flex-direction:column;width:100%;padding:5px 80px 10px 10px;list-style:none;display:flex;position:relative}.biscuitman summary b{margin-bottom:3px}.biscuitman summary b:after{content:"";border:5px solid rgba(var(--ui),.4);border-top-color:#0000;border-left-color:#0000;border-radius:2px;width:1em;height:1em;margin:-2px 0 0 -4px;display:block;transform:rotate(-45deg)scale(.3)}.biscuitman summary p{color:var(--tx);font-size:14px}.biscuitman summary>*{display:inline-flex}.biscuitman summary::marker{display:none}.biscuitman summary::-webkit-details-marker{display:none}.biscuitman dl{background:rgba(var(--ui),.08);margin:10px;padding:10px;display:flex}.biscuitman dl dt,.biscuitman dl dd{color:var(--tx);font-size:12px}.biscuitman dl dt{min-width:120px;padding-right:30px;font-weight:700}.biscuitman label{--height:1.2em;--width:2.3em;--gap:2px;height:var(--height);width:var(--width);background-color:rgba(var(--ui),.3);border-radius:var(--height);margin-top:-2px;display:block;position:absolute;top:50%;right:20px;transform:translateY(-50%);font-size:20px!important}.biscuitman label:before{content:"";background:var(--bg);height:calc(var(--height) - calc(var(--gap)*2));width:calc(var(--height) - calc(var(--gap)*2));height:var(--height);width:var(--height);left:var(--gap);transform-origin:50%;border-radius:100%;display:block;position:absolute;top:50%;left:0;transform:translateY(-50%)scale(.8)}.biscuitman label.checked{background-color:var(--c)}.biscuitman label.checked:before{left:auto;right:0}.biscuitman label:has(:focus-visible){outline:auto highlight}.biscuitman label.disabled.checked{opacity:.5}.biscuitman label input{opacity:0}`;d.head.appendChild(c)})(document); \ No newline at end of file +/*! biscuitman.js 0.3.19 */((e,t,o,a,i)=>{let n;let l={key:"myconsent",global:"Consent",force:!1,enableMore:!0,sections:["essential"],title:"Your privacy matters",message:"We use cookies",settings:"Settings",reject:"Reject All",accept:"Accept All",save:"Save My Settings",settingsTitle:"My Consent Settings",info:"",more:"Show more",noCookies:"No cookies to display",acceptNonEU:!1,dialogPolyfillUrl:"//cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.5.6/dialog-polyfill.min.js",...t.biscuitman},s=e.createElement("div"),c=()=>{a.style.setProperty("--bm-height",`${s.offsetHeight}px`)},r=e=>{a.classList.toggle("bm-show",e),c()},d=()=>{let{consentTime:e,...t}=g();for(let[i,n]of(e||(t=o.fromEntries(l.sections.slice(1).map(e=>[e,!1]))),o.entries(t)))a.classList.toggle(`bm-${i}`,n),a.classList.toggle(`bm-no-${i}`,!n)};function p(e){let t=e.target.dataset.id;switch(b("button",{id:t}),t){case"accept":k(!0);break;case"close":n.close();break;case"settings":f();break;case"save":k();break;case"reject":k(!1)}}function m(){b("close")}function u(e){l.force&&e.preventDefault()}function f(){b("open"),n.showModal()}function b(t,o){let a=`${i}:${t}`,n={...void 0!==o&&o,time:+new Date};e.dispatchEvent(new CustomEvent(a,n)),console.debug(a,n)}let g=()=>t[l.global]||{};function $(e){t[l.global]=e,d()}function h(e,t){for(let o in e)e[o]&&!1===t[o]&&b("revoke",{section:o})}function v(){try{return JSON.parse(localStorage.getItem(l.key))}catch(e){return console.error(e),localStorage.removeItem(l.key),{}}}function y(){let t=o.fromEntries(o.entries(localStorage)),a=o.fromEntries(e.cookie.split("; ").map(e=>e.split("="))),{consentTime:i,...n}=v()||l.sections.slice(1).reduce((e,t)=>(e[t]=!1,{consentTime:void 0,...e}),{});for(let[i,s]of o.entries(n)){if(s)continue;let n=o.keys(l[`${i}Cookies`]||{});for(let i of(n.filter(e=>e.endsWith("*")).map(e=>{o.keys({...a,...t}).map(t=>{t.startsWith(e.slice(0,-1))&&n.push(t)})}),n)){if(a[i]){let t=`${i}=;expires=Thu, 01 Jan 1970 00:00:01 UTC;path=/;`;e.cookie=t,e.cookie=`${t}domain=${location.hostname};`,e.cookie=`${t}domain=.${location.hostname};`,b("delete",{cookie:i})}t[i]&&(localStorage.removeItem(i),b("delete",{localStorage:i}))}}}function k(e){let t=void 0===e,o={consentTime:+new Date};l.sections.forEach(a=>{if("essential"===a)return!1;let i=s.querySelector(`[data-s=${a}]`),n=t?i.checked:e;o[a]=n,t||(i.checked=e)}),h(g(),o),$(o),localStorage.setItem(l.key,JSON.stringify(o)),b("save",{data:o}),y(),E(),n.open&&n.close(),r(!1)}function E(){e.querySelectorAll("script[data-consent]").forEach(t=>{if(!g()[t.dataset.consent])return!1;let o=e.createElement("script");for(let{name:e,value:a}of t.attributes)e.startsWith("data-")||"type"===e||o.setAttribute(e,a);o.setAttribute("type",t.dataset.type||"text/javascript"),t.src||(o.textContent=t.textContent),t.parentNode.replaceChild(o,t),b("inject",{el:t,...t.id&&{id:t.id}}),t.src&&""!==t.textContent.trim()&&o.addEventListener("load",()=>{let a=e.createElement("script");a.textContent=t.textContent,t.id&&(a.id=t.id+"-after"),o.insertAdjacentElement("afterend",a),b("inject",{el:a,parent:t,...a.id&&{id:a.id}})})})}$(v()||{});let T=Intl.DateTimeFormat().resolvedOptions().timeZone,S=/^(GMT|UTC)$/.test(T)||/(Europe|BST|CEST|CET|EET|IST|WEST|WET|GMT-1|GMT-2|UTC+1|UTC+2|UTC+3)/.test(T);l.acceptNonEU&&!S&&(k(!0),r(!1)),function(){s.classList.add(i),s.innerHTML=`
${l.title}

${l.message}

${l.settingsTitle}

${l.message}

${l.info.split("\n").map((e,t,o)=>`${e}${o.length>1&&l.enableMore&&0==t?`${l.more}`:""}`).join("")}

${l.sections.map(e=>{let t=g()[e],a="essential"===e,n=a?"disabled":"",s=a?"checked":"";void 0!==t&&(s=t?"checked":"");let c=l[`${e}Cookies`];return`
${l[`${e}Title`]}

${l[`${e}Message`]}

${c?o.entries(c).map(e=>{let[t,o]=e;return`
${t}
${o}
`}).join(""):`
${l.noCookies}
`}
`}).join("")}
`.replaceAll("{link}",`${l.linkText}`),s.querySelectorAll("button").forEach(e=>e.addEventListener("click",p)),(n=s.querySelector("dialog")).showModal&&n.close||function(){a.classList.add("bm-dialog-polyfill");let o=e.createElement("script");o.src=l.dialogPolyfillUrl,o.onload=()=>{t.dialogPolyfill.registerDialog(n)},e.head.appendChild(o);let i=e.createElement("link");i.rel="stylesheet",i.href=l.dialogPolyfillUrl.slice(0,-2)+"css",e.head.appendChild(i)}(),n.addEventListener("close",m),n.addEventListener("cancel",u);let r=s.querySelector(".more");r&&r.addEventListener("click",r.remove),s.querySelectorAll("[data-s]").forEach(e=>e.addEventListener("change",t=>{e.parentElement.classList.toggle("checked",t.target.checked)})),e.body.appendChild(s),t.addEventListener("resize",c)}(),y(),t[l.global].consentTime?(r(!1),E()):(r(!0),l.force&&f()),t.bmInvalidate=()=>{b("invalidate",{data:g()}),h({}),k(!1),$({}),localStorage.removeItem(l.key),r(!0)},t.bmUpdate=()=>{b("update",{data:g()}),f()}})(document,window,Object,document.documentElement,"biscuitman");;((d)=>{let c=d.createElement('style');c.textContent=`/*! biscuitman.js 0.3.19 */.biscuitman{--ui:0,0,0;--tx:#444;--bg:#fff;--c:#105d89;background:var(--bg);box-sizing:border-box;z-index:3;width:100%;padding:20px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;display:none;position:fixed;bottom:0;box-shadow:0 -2px 10px #00000029}.bm-show .biscuitman{display:block}.biscuitman *{box-sizing:border-box;color:var(--tx);margin:0;padding:0;font-family:inherit;font-size:16px;line-height:1.4em}.biscuitman:has([open]){transform:translateY(100%)}.biscuitman article{padding:0;position:relative}@media (min-width:770px){.biscuitman article{padding-right:calc(max(300px,30vw) + 20px)}.biscuitman article nav{width:30vw;min-width:300px;position:absolute;bottom:50%;right:0;transform:translateY(50%)}}.biscuitman article p{color:var(--tx);margin:10px 0;font-size:13px}@media (min-width:575px){.biscuitman article p{font-size:14px}}.biscuitman button{background:var(--bg);border:2px solid var(--c);color:var(--c);cursor:pointer;border-radius:3px;margin-top:10px;padding:.8em;font-size:13px;line-height:1em}.biscuitman button[data-id=accept]{background:var(--c);color:var(--bg)!important}.biscuitman button[data-id=close]{color:rgba(var(--ui),.5);opacity:.6;-webkit-user-select:none;user-select:none;z-index:2;background:0 0;border:none;outline:none;padding:10px;font-size:24px;line-height:1em;position:absolute;top:0;right:10px}.biscuitman button[disabled]{display:none}.biscuitman button:hover{opacity:.8}@media (min-width:576px){.biscuitman nav{flex-direction:row-reverse;gap:10px;width:100%;display:flex}.biscuitman nav button{flex-grow:1;margin-bottom:0}}@media (max-width:575px){.biscuitman nav{flex-direction:column;flex-grow:1;display:flex}}.biscuitman dialog{background:var(--bg);border:0;width:100%;max-width:100%;height:100%;max-height:100%}@media (min-width:576px){.biscuitman dialog{border-radius:10px;width:90vw;max-width:860px;max-height:80vh;margin:auto;box-shadow:0 0 8px #0000004d}}@media (min-width:576px) and (min-height:1134px){.biscuitman dialog{max-height:950px}}.biscuitman dialog nav{justify-self:flex-end;position:relative}.biscuitman .bm-dialog{flex-direction:column;height:100%;padding:20px;display:flex}.biscuitman .bm-dialog b{padding-bottom:8px;position:relative}.biscuitman .bm-dialog>b:after{content:"";background:linear-gradient(180deg,var(--bg)20%,#fff0);pointer-events:none;z-index:1;width:100%;height:25px;margin-bottom:-24px;position:absolute;bottom:0;left:0}.biscuitman .bm-dialog nav:after{content:"";background:linear-gradient(0deg,var(--bg)20%,#fff0);pointer-events:none;width:100%;height:25px;position:absolute;top:-24px;left:0}.biscuitman .bm-sections{scrollbar-color:rgba(var(--ui),.2)var(--bg);flex-shrink:1;height:100%;padding:15px 0;position:relative;overflow-y:scroll}@media (min-width:576px){.biscuitman .bm-sections{margin-right:-18px;padding-right:4px}}.biscuitman .bm-sections>p{padding-right:30px;font-size:13px;line-height:18px}@media (min-width:576px){.biscuitman .bm-sections>p{font-size:14px}}.biscuitman .bm-sections>p span{font-size:inherit;padding-bottom:5px;display:inline-block}.biscuitman .bm-sections>p .more~span{display:none}.biscuitman a{font-size:inherit;color:var(--c);cursor:pointer;text-decoration:none;display:inline-block}.biscuitman a:hover{text-decoration:underline}.biscuitman section{margin-bottom:10px;position:relative}.biscuitman section:first-of-type{margin-top:10px}.biscuitman details{border:1px solid rgba(var(--ui),.2);border-radius:5px;padding:10px;list-style:none;box-shadow:0 2px 4px #0000001a}.biscuitman details[open] summary b:after{margin:-3px 0 0 -2px;transform:rotate(45deg)scale(.3)}.biscuitman summary{cursor:pointer;flex-direction:column;width:100%;padding:5px 80px 10px 10px;list-style:none;display:flex;position:relative}.biscuitman summary b{margin-bottom:3px}.biscuitman summary b:after{content:"";border:5px solid rgba(var(--ui),.4);border-top-color:#0000;border-left-color:#0000;border-radius:2px;width:1em;height:1em;margin:-2px 0 0 -4px;display:block;transform:rotate(-45deg)scale(.3)}.biscuitman summary p{color:var(--tx);font-size:14px}.biscuitman summary>*{display:inline-flex}.biscuitman summary::marker{display:none}.biscuitman summary::-webkit-details-marker{display:none}.biscuitman dl{background:rgba(var(--ui),.08);margin:10px;padding:10px;display:flex}.biscuitman dl dt,.biscuitman dl dd{color:var(--tx);font-size:12px}.biscuitman dl dt{min-width:120px;padding-right:30px;font-weight:700}.biscuitman label{--height:1.2em;--width:2.3em;--gap:2px;height:var(--height);width:var(--width);background-color:rgba(var(--ui),.3);border-radius:var(--height);margin-top:-2px;display:block;position:absolute;top:50%;right:20px;transform:translateY(-50%);font-size:20px!important}.biscuitman label:before{content:"";background:var(--bg);height:calc(var(--height) - calc(var(--gap)*2));width:calc(var(--height) - calc(var(--gap)*2));height:var(--height);width:var(--height);left:var(--gap);transform-origin:50%;border-radius:100%;display:block;position:absolute;top:50%;left:0;transform:translateY(-50%)scale(.8)}.biscuitman label.checked{background-color:var(--c)}.biscuitman label.checked:before{left:auto;right:0}.biscuitman label:has(:focus-visible){outline:auto highlight}.biscuitman label.disabled.checked{opacity:.5}.biscuitman label input{opacity:0}.bm-dialog-polyfill .biscuitman dialog{position:fixed;top:50%;transform:translateY(-50%)}`;d.head.appendChild(c)})(document); \ No newline at end of file diff --git a/dist/esm/biscuitman.min.mjs b/dist/esm/biscuitman.min.mjs index d7ca1b3..0457a6f 100644 --- a/dist/esm/biscuitman.min.mjs +++ b/dist/esm/biscuitman.min.mjs @@ -1 +1 @@ -/*! biscuitman.js 0.3.18 */let e,t,o;let{document:n,window:a,Object:i}=globalThis,s=n.documentElement,c="biscuitman",l={},r={key:"myconsent",global:"Consent",force:!1,enableMore:!0,sections:["essential"],title:"Your privacy matters",message:"We use cookies",settings:"Settings",reject:"Reject All",accept:"Accept All",save:"Save My Settings",settingsTitle:"My Consent Settings",info:"",more:"Show more",noCookies:"No cookies to display",acceptNonEU:!1},d=document.createElement("div"),u=()=>{s.style.setProperty("--bm-height",`${d.offsetHeight}px`)},m=e=>{s.classList.toggle("bm-show",e),u()},p=()=>{let{consentTime:e,...o}=h();for(let[n,a]of(e||(o=i.fromEntries(t.sections.slice(1).map(e=>[e,!1]))),i.entries(o)))s.classList.toggle(`bm-${n}`,a),s.classList.toggle(`bm-no-${n}`,!a)};function f(e){let t=e.target.dataset.id;switch(v("button",{id:t}),t){case"accept":C(!0);break;case"close":o.close();break;case"settings":g();break;case"save":C();break;case"reject":C(!1)}}function b(){v("close")}function $(e){t.force&&e.preventDefault()}function g(){v("open"),o.showModal()}function v(e,t){let o=`${c}:${e}`,a={...void 0!==t&&t,time:+new Date};n.dispatchEvent(new CustomEvent(o,a)),console.debug(o,a),l[o]&&l[o].forEach(e=>e(a))}let h=()=>a[t.global]||{};function k(e){a[t.global]=e,p()}let E=e=>!!h()[e];function y(e,t){for(let o in e)e[o]&&!1===t[o]&&v("revoke",{section:o})}function T(){try{return JSON.parse(localStorage.getItem(t.key))}catch(e){return console.error(e),localStorage.removeItem(t.key),{}}}function S(){let e=i.fromEntries(i.entries(localStorage)),o=i.fromEntries(n.cookie.split("; ").map(e=>e.split("="))),{consentTime:a,...s}=T()||t.sections.slice(1).reduce((e,t)=>(e[t]=!1,{consentTime:void 0,...e}),{});for(let[a,c]of i.entries(s)){if(c)continue;let s=i.keys(t[`${a}Cookies`]||{});for(let t of(s.filter(e=>e.endsWith("*")).map(t=>{i.keys({...o,...e}).map(e=>{e.startsWith(t.slice(0,-1))&&s.push(e)})}),s)){if(o[t]){let e=`${t}=;expires=Thu, 01 Jan 1970 00:00:01 UTC;path=/;`;n.cookie=e,n.cookie=`${e}domain=${location.hostname};`,n.cookie=`${e}domain=.${location.hostname};`,v("delete",{cookie:t})}e[t]&&(localStorage.removeItem(t),v("delete",{localStorage:t}))}}}function C(e){let n=void 0===e,a={consentTime:+new Date};t.sections.forEach(t=>{if("essential"===t)return!1;let o=d.querySelector(`[data-s=${t}]`),i=n?o.checked:e;a[t]=i,n||(o.checked=e)}),y(h(),a),k(a),localStorage.setItem(t.key,JSON.stringify(a)),v("save",{data:a}),S(),j(),o.close(),m(!1)}function j(){n.querySelectorAll("script[data-consent]").forEach(e=>{if(!h()[e.dataset.consent])return!1;let t=n.createElement("script");for(let{name:o,value:n}of e.attributes)o.startsWith("data-")||"type"===o||t.setAttribute(o,n);t.setAttribute("type",e.dataset.type||"text/javascript"),e.src||(t.textContent=e.textContent),e.parentNode.replaceChild(t,e),v("inject",{el:e,...e.id&&{id:e.id}}),e.src&&""!==e.textContent.trim()&&t.addEventListener("load",()=>{let o=n.createElement("script");o.textContent=e.textContent,e.id&&(o.id=e.id+"-after"),t.insertAdjacentElement("afterend",o),v("inject",{el:o,parent:e,...o.id&&{id:o.id}})})})}export default{create:function(){let s=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(e)return e;t={...r,...s};let p=a.bmInvalidate=()=>{v("invalidate",{data:h()}),y({}),C(!1),k({}),localStorage.removeItem(t.key),m(!0)},L=a.bmUpdate=()=>{v("update",{data:h()}),g()};return k(T()||{}),function(){let e=Intl.DateTimeFormat().resolvedOptions().timeZone,o=/^(GMT|UTC)$/.test(e)||/(Europe|BST|CEST|CET|EET|IST|WEST|WET|GMT-1|GMT-2|UTC+1|UTC+2|UTC+3)/.test(e);t.acceptNonEU&&!o&&(C(!0),m(!1))}(),function(){d.classList.add("biscuitman"),d.innerHTML=`
${t.title}

${t.message}

${t.settingsTitle}

${t.message}

${t.info.split("\n").map((e,o,n)=>`${e}${n.length>1&&t.enableMore&&0==o?`${t.more}`:""}`).join("")}

${t.sections.map(e=>{let o=h()[e],n="essential"===e,a=n?"disabled":"",s=n?"checked":"";void 0!==o&&(s=o?"checked":"");let l=t[`${e}Cookies`];return`
${t[`${e}Title`]}

${t[`${e}Message`]}

${l?i.entries(l).map(e=>{let[t,o]=e;return`
${t}
${o}
`}).join(""):`
${t.noCookies}
`}
`}).join("")}
`.replaceAll("{link}",`${t.linkText}`),d.querySelectorAll("button").forEach(e=>e.addEventListener("click",f)),(o=d.querySelector("dialog")).addEventListener("close",b),o.addEventListener("cancel",$);let e=d.querySelector(".more");e&&e.addEventListener("click",e.remove),d.querySelectorAll("[data-s]").forEach(e=>e.addEventListener("change",t=>{e.parentElement.classList.toggle("checked",t.target.checked)})),n.body.appendChild(d),a.addEventListener("resize",u)}(),S(),a[t.global].consentTime?(m(!1),j()):(m(!0),t.force&&g()),e={consent:E,invalidate:p,update:L,on:(t,o)=>{let n=`${c}:${t}`;return l[n]||(l[n]=[]),l[n].push(o),e},off:(e,t)=>{let o=`${c}:${e}`;l[o]&&(l[o]=l[o].filter(e=>e!==t))}}}}; \ No newline at end of file +/*! biscuitman.js 0.3.19 */let e,t,o;let{document:a,window:n,Object:l}=globalThis,i=a.documentElement,s="biscuitman",c={},r={key:"myconsent",global:"Consent",force:!1,enableMore:!0,sections:["essential"],title:"Your privacy matters",message:"We use cookies",settings:"Settings",reject:"Reject All",accept:"Accept All",save:"Save My Settings",settingsTitle:"My Consent Settings",info:"",more:"Show more",noCookies:"No cookies to display",acceptNonEU:!1,dialogPolyfillUrl:"//cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.5.6/dialog-polyfill.min.js"},d=document.createElement("div"),p=()=>{i.style.setProperty("--bm-height",`${d.offsetHeight}px`)},u=e=>{i.classList.toggle("bm-show",e),p()},m=()=>{let{consentTime:e,...o}=v();for(let[a,n]of(e||(o=l.fromEntries(t.sections.slice(1).map(e=>[e,!1]))),l.entries(o)))i.classList.toggle(`bm-${a}`,n),i.classList.toggle(`bm-no-${a}`,!n)};function f(e){let t=e.target.dataset.id;switch(h("button",{id:t}),t){case"accept":C(!0);break;case"close":o.close();break;case"settings":$();break;case"save":C();break;case"reject":C(!1)}}function b(){h("close")}function g(e){t.force&&e.preventDefault()}function $(){h("open"),o.showModal()}function h(e,t){let o=`${s}:${e}`,n={...void 0!==t&&t,time:+new Date};a.dispatchEvent(new CustomEvent(o,n)),console.debug(o,n),c[o]&&c[o].forEach(e=>e(n))}let v=()=>n[t.global]||{};function y(e){n[t.global]=e,m()}let k=e=>!!v()[e];function E(e,t){for(let o in e)e[o]&&!1===t[o]&&h("revoke",{section:o})}function T(){try{return JSON.parse(localStorage.getItem(t.key))}catch(e){return console.error(e),localStorage.removeItem(t.key),{}}}function S(){let e=l.fromEntries(l.entries(localStorage)),o=l.fromEntries(a.cookie.split("; ").map(e=>e.split("="))),{consentTime:n,...i}=T()||t.sections.slice(1).reduce((e,t)=>(e[t]=!1,{consentTime:void 0,...e}),{});for(let[n,s]of l.entries(i)){if(s)continue;let i=l.keys(t[`${n}Cookies`]||{});for(let t of(i.filter(e=>e.endsWith("*")).map(t=>{l.keys({...o,...e}).map(e=>{e.startsWith(t.slice(0,-1))&&i.push(e)})}),i)){if(o[t]){let e=`${t}=;expires=Thu, 01 Jan 1970 00:00:01 UTC;path=/;`;a.cookie=e,a.cookie=`${e}domain=${location.hostname};`,a.cookie=`${e}domain=.${location.hostname};`,h("delete",{cookie:t})}e[t]&&(localStorage.removeItem(t),h("delete",{localStorage:t}))}}}function C(e){let a=void 0===e,n={consentTime:+new Date};t.sections.forEach(t=>{if("essential"===t)return!1;let o=d.querySelector(`[data-s=${t}]`),l=a?o.checked:e;n[t]=l,a||(o.checked=e)}),E(v(),n),y(n),localStorage.setItem(t.key,JSON.stringify(n)),h("save",{data:n}),S(),j(),o.open&&o.close(),u(!1)}function j(){a.querySelectorAll("script[data-consent]").forEach(e=>{if(!v()[e.dataset.consent])return!1;let t=a.createElement("script");for(let{name:o,value:a}of e.attributes)o.startsWith("data-")||"type"===o||t.setAttribute(o,a);t.setAttribute("type",e.dataset.type||"text/javascript"),e.src||(t.textContent=e.textContent),e.parentNode.replaceChild(t,e),h("inject",{el:e,...e.id&&{id:e.id}}),e.src&&""!==e.textContent.trim()&&t.addEventListener("load",()=>{let o=a.createElement("script");o.textContent=e.textContent,e.id&&(o.id=e.id+"-after"),t.insertAdjacentElement("afterend",o),h("inject",{el:o,parent:e,...o.id&&{id:o.id}})})})}export default{create:function(){let m=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(e)return e;t={...r,...m};let L=n.bmInvalidate=()=>{h("invalidate",{data:v()}),E({}),C(!1),y({}),localStorage.removeItem(t.key),u(!0)},x=n.bmUpdate=()=>{h("update",{data:v()}),$()};return y(T()||{}),function(){let e=Intl.DateTimeFormat().resolvedOptions().timeZone,o=/^(GMT|UTC)$/.test(e)||/(Europe|BST|CEST|CET|EET|IST|WEST|WET|GMT-1|GMT-2|UTC+1|UTC+2|UTC+3)/.test(e);t.acceptNonEU&&!o&&(C(!0),u(!1))}(),function(){d.classList.add("biscuitman"),d.innerHTML=`
${t.title}

${t.message}

${t.settingsTitle}

${t.message}

${t.info.split("\n").map((e,o,a)=>`${e}${a.length>1&&t.enableMore&&0==o?`${t.more}`:""}`).join("")}

${t.sections.map(e=>{let o=v()[e],a="essential"===e,n=a?"disabled":"",i=a?"checked":"";void 0!==o&&(i=o?"checked":"");let c=t[`${e}Cookies`];return`
${t[`${e}Title`]}

${t[`${e}Message`]}

${c?l.entries(c).map(e=>{let[t,o]=e;return`
${t}
${o}
`}).join(""):`
${t.noCookies}
`}
`}).join("")}
`.replaceAll("{link}",`${t.linkText}`),d.querySelectorAll("button").forEach(e=>e.addEventListener("click",f)),(o=d.querySelector("dialog")).showModal&&o.close||function(){i.classList.add("bm-dialog-polyfill");let e=a.createElement("script");e.src=t.dialogPolyfillUrl,e.onload=()=>{n.dialogPolyfill.registerDialog(o)},a.head.appendChild(e);let l=a.createElement("link");l.rel="stylesheet",l.href=t.dialogPolyfillUrl.slice(0,-2)+"css",a.head.appendChild(l)}(),o.addEventListener("close",b),o.addEventListener("cancel",g);let e=d.querySelector(".more");e&&e.addEventListener("click",e.remove),d.querySelectorAll("[data-s]").forEach(e=>e.addEventListener("change",t=>{e.parentElement.classList.toggle("checked",t.target.checked)})),a.body.appendChild(d),n.addEventListener("resize",p)}(),S(),n[t.global].consentTime?(u(!1),j()):(u(!0),t.force&&$()),e={consent:k,invalidate:L,update:x,on:(t,o)=>{let a=`${s}:${t}`;return c[a]||(c[a]=[]),c[a].push(o),e},off:(e,t)=>{let o=`${s}:${e}`;c[o]&&(c[o]=c[o].filter(e=>e!==t))}}}}; \ No newline at end of file diff --git a/dist/esm/biscuitman.mjs b/dist/esm/biscuitman.mjs index 49c8c8f..6401cb3 100644 --- a/dist/esm/biscuitman.mjs +++ b/dist/esm/biscuitman.mjs @@ -1,4 +1,4 @@ -/*! biscuitman.js 0.3.18 */ +/*! biscuitman.js 0.3.19 */ const { document: d, window: w, Object: O } = globalThis; const h = d.documentElement; const bm = 'biscuitman'; @@ -23,7 +23,8 @@ const defaults = { info: '', more: 'Show more', noCookies: 'No cookies to display', - acceptNonEU: false + acceptNonEU: false, + dialogPolyfillUrl: '//cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.5.6/dialog-polyfill.min.js' }; // UI & Events: const ui = document.createElement('div'); @@ -83,6 +84,7 @@ function render() { `.replaceAll('{link}', `${options.linkText}`); ui.querySelectorAll('button').forEach((b)=>b.addEventListener('click', buttonHandler)); dialog = ui.querySelector('dialog'); + if (!dialog.showModal || !dialog.close) loadDialogPolyfill(); dialog.addEventListener('close', closeModalHandler); dialog.addEventListener('cancel', cancelModalHandler); const moreLink = ui.querySelector('.more'); @@ -238,7 +240,7 @@ function saveConsents(value) { }); clearStorages(); insertScripts(); - dialog.close(); + if (dialog.open) dialog.close(); displayUI(false); } function insertScripts() { @@ -283,6 +285,20 @@ function handleNonEUConsent() { displayUI(false); } } +function loadDialogPolyfill() { + // https://github.com/GoogleChrome/dialog-polyfill + h.classList.add('bm-dialog-polyfill'); + const script = d.createElement('script'); + script.src = options.dialogPolyfillUrl; + script.onload = ()=>{ + w.dialogPolyfill.registerDialog(dialog); + }; + d.head.appendChild(script); + const link = d.createElement('link'); + link.rel = 'stylesheet'; + link.href = options.dialogPolyfillUrl.slice(0, -2) + 'css'; + d.head.appendChild(link); +} function create() { let config = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}; if (instance) return instance; diff --git a/dist/esm/biscuitman.withcss.min.mjs b/dist/esm/biscuitman.withcss.min.mjs index 9465a7c..ed1a45e 100644 --- a/dist/esm/biscuitman.withcss.min.mjs +++ b/dist/esm/biscuitman.withcss.min.mjs @@ -1 +1 @@ -/*! biscuitman.js 0.3.18 */let e,t,o;let{document:n,window:a,Object:i}=globalThis,s=n.documentElement,c="biscuitman",l={},r={key:"myconsent",global:"Consent",force:!1,enableMore:!0,sections:["essential"],title:"Your privacy matters",message:"We use cookies",settings:"Settings",reject:"Reject All",accept:"Accept All",save:"Save My Settings",settingsTitle:"My Consent Settings",info:"",more:"Show more",noCookies:"No cookies to display",acceptNonEU:!1},d=document.createElement("div"),u=()=>{s.style.setProperty("--bm-height",`${d.offsetHeight}px`)},m=e=>{s.classList.toggle("bm-show",e),u()},p=()=>{let{consentTime:e,...o}=h();for(let[n,a]of(e||(o=i.fromEntries(t.sections.slice(1).map(e=>[e,!1]))),i.entries(o)))s.classList.toggle(`bm-${n}`,a),s.classList.toggle(`bm-no-${n}`,!a)};function f(e){let t=e.target.dataset.id;switch(v("button",{id:t}),t){case"accept":C(!0);break;case"close":o.close();break;case"settings":g();break;case"save":C();break;case"reject":C(!1)}}function b(){v("close")}function $(e){t.force&&e.preventDefault()}function g(){v("open"),o.showModal()}function v(e,t){let o=`${c}:${e}`,a={...void 0!==t&&t,time:+new Date};n.dispatchEvent(new CustomEvent(o,a)),console.debug(o,a),l[o]&&l[o].forEach(e=>e(a))}let h=()=>a[t.global]||{};function k(e){a[t.global]=e,p()}let E=e=>!!h()[e];function y(e,t){for(let o in e)e[o]&&!1===t[o]&&v("revoke",{section:o})}function T(){try{return JSON.parse(localStorage.getItem(t.key))}catch(e){return console.error(e),localStorage.removeItem(t.key),{}}}function S(){let e=i.fromEntries(i.entries(localStorage)),o=i.fromEntries(n.cookie.split("; ").map(e=>e.split("="))),{consentTime:a,...s}=T()||t.sections.slice(1).reduce((e,t)=>(e[t]=!1,{consentTime:void 0,...e}),{});for(let[a,c]of i.entries(s)){if(c)continue;let s=i.keys(t[`${a}Cookies`]||{});for(let t of(s.filter(e=>e.endsWith("*")).map(t=>{i.keys({...o,...e}).map(e=>{e.startsWith(t.slice(0,-1))&&s.push(e)})}),s)){if(o[t]){let e=`${t}=;expires=Thu, 01 Jan 1970 00:00:01 UTC;path=/;`;n.cookie=e,n.cookie=`${e}domain=${location.hostname};`,n.cookie=`${e}domain=.${location.hostname};`,v("delete",{cookie:t})}e[t]&&(localStorage.removeItem(t),v("delete",{localStorage:t}))}}}function C(e){let n=void 0===e,a={consentTime:+new Date};t.sections.forEach(t=>{if("essential"===t)return!1;let o=d.querySelector(`[data-s=${t}]`),i=n?o.checked:e;a[t]=i,n||(o.checked=e)}),y(h(),a),k(a),localStorage.setItem(t.key,JSON.stringify(a)),v("save",{data:a}),S(),j(),o.close(),m(!1)}function j(){n.querySelectorAll("script[data-consent]").forEach(e=>{if(!h()[e.dataset.consent])return!1;let t=n.createElement("script");for(let{name:o,value:n}of e.attributes)o.startsWith("data-")||"type"===o||t.setAttribute(o,n);t.setAttribute("type",e.dataset.type||"text/javascript"),e.src||(t.textContent=e.textContent),e.parentNode.replaceChild(t,e),v("inject",{el:e,...e.id&&{id:e.id}}),e.src&&""!==e.textContent.trim()&&t.addEventListener("load",()=>{let o=n.createElement("script");o.textContent=e.textContent,e.id&&(o.id=e.id+"-after"),t.insertAdjacentElement("afterend",o),v("inject",{el:o,parent:e,...o.id&&{id:o.id}})})})}export default{create:function(){let s=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(e)return e;t={...r,...s};let p=a.bmInvalidate=()=>{v("invalidate",{data:h()}),y({}),C(!1),k({}),localStorage.removeItem(t.key),m(!0)},L=a.bmUpdate=()=>{v("update",{data:h()}),g()};return k(T()||{}),function(){let e=Intl.DateTimeFormat().resolvedOptions().timeZone,o=/^(GMT|UTC)$/.test(e)||/(Europe|BST|CEST|CET|EET|IST|WEST|WET|GMT-1|GMT-2|UTC+1|UTC+2|UTC+3)/.test(e);t.acceptNonEU&&!o&&(C(!0),m(!1))}(),function(){d.classList.add("biscuitman"),d.innerHTML=`
${t.title}

${t.message}

${t.settingsTitle}

${t.message}

${t.info.split("\n").map((e,o,n)=>`${e}${n.length>1&&t.enableMore&&0==o?`${t.more}`:""}`).join("")}

${t.sections.map(e=>{let o=h()[e],n="essential"===e,a=n?"disabled":"",s=n?"checked":"";void 0!==o&&(s=o?"checked":"");let l=t[`${e}Cookies`];return`
${t[`${e}Title`]}

${t[`${e}Message`]}

${l?i.entries(l).map(e=>{let[t,o]=e;return`
${t}
${o}
`}).join(""):`
${t.noCookies}
`}
`}).join("")}
`.replaceAll("{link}",`${t.linkText}`),d.querySelectorAll("button").forEach(e=>e.addEventListener("click",f)),(o=d.querySelector("dialog")).addEventListener("close",b),o.addEventListener("cancel",$);let e=d.querySelector(".more");e&&e.addEventListener("click",e.remove),d.querySelectorAll("[data-s]").forEach(e=>e.addEventListener("change",t=>{e.parentElement.classList.toggle("checked",t.target.checked)})),n.body.appendChild(d),a.addEventListener("resize",u)}(),S(),a[t.global].consentTime?(m(!1),j()):(m(!0),t.force&&g()),e={consent:E,invalidate:p,update:L,on:(t,o)=>{let n=`${c}:${t}`;return l[n]||(l[n]=[]),l[n].push(o),e},off:(e,t)=>{let o=`${c}:${e}`;l[o]&&(l[o]=l[o].filter(e=>e!==t))}}}};;if(typeof BMCSS==='undefined'){let c=document.createElement('style');c.id='BMCSS';c.textContent=`/*! biscuitman.js 0.3.18 */.biscuitman{--ui:0,0,0;--tx:#444;--bg:#fff;--c:#105d89;background:var(--bg);box-sizing:border-box;z-index:3;width:100%;padding:20px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;display:none;position:fixed;bottom:0;box-shadow:0 -2px 10px #00000029}html.bm-show .biscuitman{display:block}.biscuitman *{box-sizing:border-box;color:var(--tx);margin:0;padding:0;font-family:inherit;font-size:16px;line-height:1.4em}.biscuitman:has([open]){transform:translateY(100%)}.biscuitman article{padding:0;position:relative}@media (min-width:770px){.biscuitman article{padding-right:calc(max(300px,30vw) + 20px)}.biscuitman article nav{width:30vw;min-width:300px;position:absolute;bottom:50%;right:0;transform:translateY(50%)}}.biscuitman article p{color:var(--tx);margin:10px 0;font-size:13px}@media (min-width:575px){.biscuitman article p{font-size:14px}}.biscuitman button{background:var(--bg);border:2px solid var(--c);color:var(--c);cursor:pointer;border-radius:3px;margin-top:10px;padding:.8em;font-size:13px;line-height:1em}.biscuitman button[data-id=accept]{background:var(--c);color:var(--bg)!important}.biscuitman button[data-id=close]{color:rgba(var(--ui),.5);opacity:.6;-webkit-user-select:none;user-select:none;z-index:2;background:0 0;border:none;outline:none;padding:10px;font-size:24px;line-height:1em;position:absolute;top:0;right:10px}.biscuitman button[disabled]{display:none}.biscuitman button:hover{opacity:.8}@media (min-width:576px){.biscuitman nav{flex-direction:row-reverse;gap:10px;width:100%;display:flex}.biscuitman nav button{flex-grow:1;margin-bottom:0}}@media (max-width:575px){.biscuitman nav{flex-direction:column;flex-grow:1;display:flex}}.biscuitman dialog{background:var(--bg);border:0;width:100%;max-width:100%;height:100%;max-height:100%}@media (min-width:576px){.biscuitman dialog{border-radius:10px;width:90vw;max-width:860px;max-height:80vh;margin:auto;box-shadow:0 0 8px #0000004d}}@media (min-width:576px) and (min-height:1134px){.biscuitman dialog{max-height:950px}}.biscuitman dialog nav{justify-self:flex-end;position:relative}.biscuitman .bm-dialog{flex-direction:column;height:100%;padding:20px;display:flex}.biscuitman .bm-dialog b{padding-bottom:8px;position:relative}.biscuitman .bm-dialog>b:after{content:"";background:linear-gradient(180deg,var(--bg)20%,transparent);pointer-events:none;z-index:1;width:100%;height:25px;margin-bottom:-24px;position:absolute;bottom:0;left:0}.biscuitman .bm-dialog nav:after{content:"";background:linear-gradient(0deg,var(--bg)20%,transparent);pointer-events:none;width:100%;height:25px;position:absolute;top:-24px;left:0}.biscuitman .bm-sections{scrollbar-color:rgba(var(--ui),.2)var(--bg);flex-shrink:1;height:100%;padding:15px 0;position:relative;overflow-y:scroll}@media (min-width:576px){.biscuitman .bm-sections{margin-right:-18px;padding-right:4px}}.biscuitman .bm-sections>p{padding-right:30px;font-size:13px;line-height:18px}@media (min-width:576px){.biscuitman .bm-sections>p{font-size:14px}}.biscuitman .bm-sections>p span{font-size:inherit;padding-bottom:5px;display:inline-block}.biscuitman .bm-sections>p .more~span{display:none}.biscuitman a{font-size:inherit;color:var(--c);cursor:pointer;text-decoration:none;display:inline-block}.biscuitman a:hover{text-decoration:underline}.biscuitman section{margin-bottom:10px;position:relative}.biscuitman section:first-of-type{margin-top:10px}.biscuitman details{border:1px solid rgba(var(--ui),.2);border-radius:5px;padding:10px;list-style:none;box-shadow:0 2px 4px #0000001a}.biscuitman details[open] summary b:after{margin:-3px 0 0 -2px;transform:rotate(45deg)scale(.3)}.biscuitman summary{cursor:pointer;flex-direction:column;width:100%;padding:5px 80px 10px 10px;list-style:none;display:flex;position:relative}.biscuitman summary b{margin-bottom:3px}.biscuitman summary b:after{content:"";border:5px solid rgba(var(--ui),.4);border-top-color:#0000;border-left-color:#0000;border-radius:2px;width:1em;height:1em;margin:-2px 0 0 -4px;display:block;transform:rotate(-45deg)scale(.3)}.biscuitman summary p{color:var(--tx);font-size:14px}.biscuitman summary>*{display:inline-flex}.biscuitman summary::marker{display:none}.biscuitman summary::-webkit-details-marker{display:none}.biscuitman dl{background:rgba(var(--ui),.08);margin:10px;padding:10px;display:flex}.biscuitman dl dt,.biscuitman dl dd{color:var(--tx);font-size:12px}.biscuitman dl dt{min-width:120px;padding-right:30px;font-weight:700}.biscuitman label{--height:1.2em;--width:2.3em;--gap:2px;height:var(--height);width:var(--width);background-color:rgba(var(--ui),.3);border-radius:var(--height);margin-top:-2px;display:block;position:absolute;top:50%;right:20px;transform:translateY(-50%);font-size:20px!important}.biscuitman label:before{content:"";background:var(--bg);height:calc(var(--height) - calc(var(--gap)*2));width:calc(var(--height) - calc(var(--gap)*2));height:var(--height);width:var(--height);left:var(--gap);transform-origin:50%;border-radius:100%;display:block;position:absolute;top:50%;left:0;transform:translateY(-50%)scale(.8)}.biscuitman label.checked{background-color:var(--c)}.biscuitman label.checked:before{left:auto;right:0}.biscuitman label:has(:focus-visible){outline:auto highlight}.biscuitman label.disabled.checked{opacity:.5}.biscuitman label input{opacity:0}`;document.head.appendChild(c)} \ No newline at end of file +/*! biscuitman.js 0.3.19 */let e,t,o;let{document:a,window:n,Object:l}=globalThis,i=a.documentElement,s="biscuitman",c={},r={key:"myconsent",global:"Consent",force:!1,enableMore:!0,sections:["essential"],title:"Your privacy matters",message:"We use cookies",settings:"Settings",reject:"Reject All",accept:"Accept All",save:"Save My Settings",settingsTitle:"My Consent Settings",info:"",more:"Show more",noCookies:"No cookies to display",acceptNonEU:!1,dialogPolyfillUrl:"//cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.5.6/dialog-polyfill.min.js"},d=document.createElement("div"),p=()=>{i.style.setProperty("--bm-height",`${d.offsetHeight}px`)},u=e=>{i.classList.toggle("bm-show",e),p()},m=()=>{let{consentTime:e,...o}=v();for(let[a,n]of(e||(o=l.fromEntries(t.sections.slice(1).map(e=>[e,!1]))),l.entries(o)))i.classList.toggle(`bm-${a}`,n),i.classList.toggle(`bm-no-${a}`,!n)};function f(e){let t=e.target.dataset.id;switch(h("button",{id:t}),t){case"accept":C(!0);break;case"close":o.close();break;case"settings":$();break;case"save":C();break;case"reject":C(!1)}}function b(){h("close")}function g(e){t.force&&e.preventDefault()}function $(){h("open"),o.showModal()}function h(e,t){let o=`${s}:${e}`,n={...void 0!==t&&t,time:+new Date};a.dispatchEvent(new CustomEvent(o,n)),console.debug(o,n),c[o]&&c[o].forEach(e=>e(n))}let v=()=>n[t.global]||{};function y(e){n[t.global]=e,m()}let k=e=>!!v()[e];function E(e,t){for(let o in e)e[o]&&!1===t[o]&&h("revoke",{section:o})}function T(){try{return JSON.parse(localStorage.getItem(t.key))}catch(e){return console.error(e),localStorage.removeItem(t.key),{}}}function S(){let e=l.fromEntries(l.entries(localStorage)),o=l.fromEntries(a.cookie.split("; ").map(e=>e.split("="))),{consentTime:n,...i}=T()||t.sections.slice(1).reduce((e,t)=>(e[t]=!1,{consentTime:void 0,...e}),{});for(let[n,s]of l.entries(i)){if(s)continue;let i=l.keys(t[`${n}Cookies`]||{});for(let t of(i.filter(e=>e.endsWith("*")).map(t=>{l.keys({...o,...e}).map(e=>{e.startsWith(t.slice(0,-1))&&i.push(e)})}),i)){if(o[t]){let e=`${t}=;expires=Thu, 01 Jan 1970 00:00:01 UTC;path=/;`;a.cookie=e,a.cookie=`${e}domain=${location.hostname};`,a.cookie=`${e}domain=.${location.hostname};`,h("delete",{cookie:t})}e[t]&&(localStorage.removeItem(t),h("delete",{localStorage:t}))}}}function C(e){let a=void 0===e,n={consentTime:+new Date};t.sections.forEach(t=>{if("essential"===t)return!1;let o=d.querySelector(`[data-s=${t}]`),l=a?o.checked:e;n[t]=l,a||(o.checked=e)}),E(v(),n),y(n),localStorage.setItem(t.key,JSON.stringify(n)),h("save",{data:n}),S(),j(),o.open&&o.close(),u(!1)}function j(){a.querySelectorAll("script[data-consent]").forEach(e=>{if(!v()[e.dataset.consent])return!1;let t=a.createElement("script");for(let{name:o,value:a}of e.attributes)o.startsWith("data-")||"type"===o||t.setAttribute(o,a);t.setAttribute("type",e.dataset.type||"text/javascript"),e.src||(t.textContent=e.textContent),e.parentNode.replaceChild(t,e),h("inject",{el:e,...e.id&&{id:e.id}}),e.src&&""!==e.textContent.trim()&&t.addEventListener("load",()=>{let o=a.createElement("script");o.textContent=e.textContent,e.id&&(o.id=e.id+"-after"),t.insertAdjacentElement("afterend",o),h("inject",{el:o,parent:e,...o.id&&{id:o.id}})})})}export default{create:function(){let m=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(e)return e;t={...r,...m};let L=n.bmInvalidate=()=>{h("invalidate",{data:v()}),E({}),C(!1),y({}),localStorage.removeItem(t.key),u(!0)},x=n.bmUpdate=()=>{h("update",{data:v()}),$()};return y(T()||{}),function(){let e=Intl.DateTimeFormat().resolvedOptions().timeZone,o=/^(GMT|UTC)$/.test(e)||/(Europe|BST|CEST|CET|EET|IST|WEST|WET|GMT-1|GMT-2|UTC+1|UTC+2|UTC+3)/.test(e);t.acceptNonEU&&!o&&(C(!0),u(!1))}(),function(){d.classList.add("biscuitman"),d.innerHTML=`
${t.title}

${t.message}

${t.settingsTitle}

${t.message}

${t.info.split("\n").map((e,o,a)=>`${e}${a.length>1&&t.enableMore&&0==o?`${t.more}`:""}`).join("")}

${t.sections.map(e=>{let o=v()[e],a="essential"===e,n=a?"disabled":"",i=a?"checked":"";void 0!==o&&(i=o?"checked":"");let c=t[`${e}Cookies`];return`
${t[`${e}Title`]}

${t[`${e}Message`]}

${c?l.entries(c).map(e=>{let[t,o]=e;return`
${t}
${o}
`}).join(""):`
${t.noCookies}
`}
`}).join("")}
`.replaceAll("{link}",`${t.linkText}`),d.querySelectorAll("button").forEach(e=>e.addEventListener("click",f)),(o=d.querySelector("dialog")).showModal&&o.close||function(){i.classList.add("bm-dialog-polyfill");let e=a.createElement("script");e.src=t.dialogPolyfillUrl,e.onload=()=>{n.dialogPolyfill.registerDialog(o)},a.head.appendChild(e);let l=a.createElement("link");l.rel="stylesheet",l.href=t.dialogPolyfillUrl.slice(0,-2)+"css",a.head.appendChild(l)}(),o.addEventListener("close",b),o.addEventListener("cancel",g);let e=d.querySelector(".more");e&&e.addEventListener("click",e.remove),d.querySelectorAll("[data-s]").forEach(e=>e.addEventListener("change",t=>{e.parentElement.classList.toggle("checked",t.target.checked)})),a.body.appendChild(d),n.addEventListener("resize",p)}(),S(),n[t.global].consentTime?(u(!1),j()):(u(!0),t.force&&$()),e={consent:k,invalidate:L,update:x,on:(t,o)=>{let a=`${s}:${t}`;return c[a]||(c[a]=[]),c[a].push(o),e},off:(e,t)=>{let o=`${s}:${e}`;c[o]&&(c[o]=c[o].filter(e=>e!==t))}}}};;if(typeof BMCSS==='undefined'){let c=document.createElement('style');c.id='BMCSS';c.textContent=`/*! biscuitman.js 0.3.19 */.biscuitman{--ui:0,0,0;--tx:#444;--bg:#fff;--c:#105d89;background:var(--bg);box-sizing:border-box;z-index:3;width:100%;padding:20px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;display:none;position:fixed;bottom:0;box-shadow:0 -2px 10px #00000029}.bm-show .biscuitman{display:block}.biscuitman *{box-sizing:border-box;color:var(--tx);margin:0;padding:0;font-family:inherit;font-size:16px;line-height:1.4em}.biscuitman:has([open]){transform:translateY(100%)}.biscuitman article{padding:0;position:relative}@media (min-width:770px){.biscuitman article{padding-right:calc(max(300px,30vw) + 20px)}.biscuitman article nav{width:30vw;min-width:300px;position:absolute;bottom:50%;right:0;transform:translateY(50%)}}.biscuitman article p{color:var(--tx);margin:10px 0;font-size:13px}@media (min-width:575px){.biscuitman article p{font-size:14px}}.biscuitman button{background:var(--bg);border:2px solid var(--c);color:var(--c);cursor:pointer;border-radius:3px;margin-top:10px;padding:.8em;font-size:13px;line-height:1em}.biscuitman button[data-id=accept]{background:var(--c);color:var(--bg)!important}.biscuitman button[data-id=close]{color:rgba(var(--ui),.5);opacity:.6;-webkit-user-select:none;user-select:none;z-index:2;background:0 0;border:none;outline:none;padding:10px;font-size:24px;line-height:1em;position:absolute;top:0;right:10px}.biscuitman button[disabled]{display:none}.biscuitman button:hover{opacity:.8}@media (min-width:576px){.biscuitman nav{flex-direction:row-reverse;gap:10px;width:100%;display:flex}.biscuitman nav button{flex-grow:1;margin-bottom:0}}@media (max-width:575px){.biscuitman nav{flex-direction:column;flex-grow:1;display:flex}}.biscuitman dialog{background:var(--bg);border:0;width:100%;max-width:100%;height:100%;max-height:100%}@media (min-width:576px){.biscuitman dialog{border-radius:10px;width:90vw;max-width:860px;max-height:80vh;margin:auto;box-shadow:0 0 8px #0000004d}}@media (min-width:576px) and (min-height:1134px){.biscuitman dialog{max-height:950px}}.biscuitman dialog nav{justify-self:flex-end;position:relative}.biscuitman .bm-dialog{flex-direction:column;height:100%;padding:20px;display:flex}.biscuitman .bm-dialog b{padding-bottom:8px;position:relative}.biscuitman .bm-dialog>b:after{content:"";background:linear-gradient(180deg,var(--bg)20%,#fff0);pointer-events:none;z-index:1;width:100%;height:25px;margin-bottom:-24px;position:absolute;bottom:0;left:0}.biscuitman .bm-dialog nav:after{content:"";background:linear-gradient(0deg,var(--bg)20%,#fff0);pointer-events:none;width:100%;height:25px;position:absolute;top:-24px;left:0}.biscuitman .bm-sections{scrollbar-color:rgba(var(--ui),.2)var(--bg);flex-shrink:1;height:100%;padding:15px 0;position:relative;overflow-y:scroll}@media (min-width:576px){.biscuitman .bm-sections{margin-right:-18px;padding-right:4px}}.biscuitman .bm-sections>p{padding-right:30px;font-size:13px;line-height:18px}@media (min-width:576px){.biscuitman .bm-sections>p{font-size:14px}}.biscuitman .bm-sections>p span{font-size:inherit;padding-bottom:5px;display:inline-block}.biscuitman .bm-sections>p .more~span{display:none}.biscuitman a{font-size:inherit;color:var(--c);cursor:pointer;text-decoration:none;display:inline-block}.biscuitman a:hover{text-decoration:underline}.biscuitman section{margin-bottom:10px;position:relative}.biscuitman section:first-of-type{margin-top:10px}.biscuitman details{border:1px solid rgba(var(--ui),.2);border-radius:5px;padding:10px;list-style:none;box-shadow:0 2px 4px #0000001a}.biscuitman details[open] summary b:after{margin:-3px 0 0 -2px;transform:rotate(45deg)scale(.3)}.biscuitman summary{cursor:pointer;flex-direction:column;width:100%;padding:5px 80px 10px 10px;list-style:none;display:flex;position:relative}.biscuitman summary b{margin-bottom:3px}.biscuitman summary b:after{content:"";border:5px solid rgba(var(--ui),.4);border-top-color:#0000;border-left-color:#0000;border-radius:2px;width:1em;height:1em;margin:-2px 0 0 -4px;display:block;transform:rotate(-45deg)scale(.3)}.biscuitman summary p{color:var(--tx);font-size:14px}.biscuitman summary>*{display:inline-flex}.biscuitman summary::marker{display:none}.biscuitman summary::-webkit-details-marker{display:none}.biscuitman dl{background:rgba(var(--ui),.08);margin:10px;padding:10px;display:flex}.biscuitman dl dt,.biscuitman dl dd{color:var(--tx);font-size:12px}.biscuitman dl dt{min-width:120px;padding-right:30px;font-weight:700}.biscuitman label{--height:1.2em;--width:2.3em;--gap:2px;height:var(--height);width:var(--width);background-color:rgba(var(--ui),.3);border-radius:var(--height);margin-top:-2px;display:block;position:absolute;top:50%;right:20px;transform:translateY(-50%);font-size:20px!important}.biscuitman label:before{content:"";background:var(--bg);height:calc(var(--height) - calc(var(--gap)*2));width:calc(var(--height) - calc(var(--gap)*2));height:var(--height);width:var(--height);left:var(--gap);transform-origin:50%;border-radius:100%;display:block;position:absolute;top:50%;left:0;transform:translateY(-50%)scale(.8)}.biscuitman label.checked{background-color:var(--c)}.biscuitman label.checked:before{left:auto;right:0}.biscuitman label:has(:focus-visible){outline:auto highlight}.biscuitman label.disabled.checked{opacity:.5}.biscuitman label input{opacity:0}.bm-dialog-polyfill .biscuitman dialog{position:fixed;top:50%;transform:translateY(-50%)}`;document.head.appendChild(c)} \ No newline at end of file diff --git a/dist/esm/biscuitman.withcss.mjs b/dist/esm/biscuitman.withcss.mjs index 3b0b5e2..dc1ffde 100644 --- a/dist/esm/biscuitman.withcss.mjs +++ b/dist/esm/biscuitman.withcss.mjs @@ -1,4 +1,4 @@ -/*! biscuitman.js 0.3.18 */ +/*! biscuitman.js 0.3.19 */ const { document: d, window: w, Object: O } = globalThis; const h = d.documentElement; const bm = 'biscuitman'; @@ -23,7 +23,8 @@ const defaults = { info: '', more: 'Show more', noCookies: 'No cookies to display', - acceptNonEU: false + acceptNonEU: false, + dialogPolyfillUrl: '//cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.5.6/dialog-polyfill.min.js' }; // UI & Events: const ui = document.createElement('div'); @@ -83,6 +84,7 @@ function render() { `.replaceAll('{link}', `${options.linkText}`); ui.querySelectorAll('button').forEach((b)=>b.addEventListener('click', buttonHandler)); dialog = ui.querySelector('dialog'); + if (!dialog.showModal || !dialog.close) loadDialogPolyfill(); dialog.addEventListener('close', closeModalHandler); dialog.addEventListener('cancel', cancelModalHandler); const moreLink = ui.querySelector('.more'); @@ -238,7 +240,7 @@ function saveConsents(value) { }); clearStorages(); insertScripts(); - dialog.close(); + if (dialog.open) dialog.close(); displayUI(false); } function insertScripts() { @@ -283,6 +285,20 @@ function handleNonEUConsent() { displayUI(false); } } +function loadDialogPolyfill() { + // https://github.com/GoogleChrome/dialog-polyfill + h.classList.add('bm-dialog-polyfill'); + const script = d.createElement('script'); + script.src = options.dialogPolyfillUrl; + script.onload = ()=>{ + w.dialogPolyfill.registerDialog(dialog); + }; + d.head.appendChild(script); + const link = d.createElement('link'); + link.rel = 'stylesheet'; + link.href = options.dialogPolyfillUrl.slice(0, -2) + 'css'; + d.head.appendChild(link); +} function create() { let config = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}; if (instance) return instance; @@ -352,7 +368,7 @@ export default { if (typeof BMCSS === 'undefined') { let css=document.createElement('style'); css.id = 'BMCSS'; - css.textContent=`/*! biscuitman.js 0.3.18 */ + css.textContent=`/*! biscuitman.js 0.3.19 */ .biscuitman { --ui: 0, 0, 0; --tx: #444; @@ -370,7 +386,7 @@ if (typeof BMCSS === 'undefined') { box-shadow: 0 -2px 10px #00000029; } -html.bm-show .biscuitman { +.bm-show .biscuitman { display: block; } @@ -529,7 +545,7 @@ html.bm-show .biscuitman { .biscuitman .bm-dialog > b:after { content: ""; - background: linear-gradient(180deg, var(--bg) 20%, transparent); + background: linear-gradient(180deg, var(--bg) 20%, #fff0); pointer-events: none; z-index: 1; width: 100%; @@ -542,7 +558,7 @@ html.bm-show .biscuitman { .biscuitman .bm-dialog nav:after { content: ""; - background: linear-gradient(0deg, var(--bg) 20%, transparent); + background: linear-gradient(0deg, var(--bg) 20%, #fff0); pointer-events: none; width: 100%; height: 25px; @@ -739,6 +755,12 @@ html.bm-show .biscuitman { .biscuitman label input { opacity: 0; } + +.bm-dialog-polyfill .biscuitman dialog { + position: fixed; + top: 50%; + transform: translateY(-50%); +} `; document.head.appendChild(css) } \ No newline at end of file diff --git a/index-esm.html b/index-esm.html index 38c641c..bde1eba 100644 --- a/index-esm.html +++ b/index-esm.html @@ -185,8 +185,8 @@
-

🍪 biscuitman.js (ESM)

-

Lightweight Consent Manager (<4kB)

+

🍪 biscuitman.js

+

Lightweight Consent Manager (ESM version)

diff --git a/index.html b/index.html index 844c64a..c5d0934 100644 --- a/index.html +++ b/index.html @@ -175,7 +175,7 @@

🍪 biscuitman.js

-

Lightweight Consent Manager (<4kB)

+

Lightweight Consent Manager

diff --git a/package.json b/package.json index 2da7cc6..d420384 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "biscuitman", - "version": "0.3.18", + "version": "0.3.19", "description": "Super lightweight open-source privacy consent manager for your website ", "browser": "biscuitman.js", "keywords": [ diff --git a/run.js b/run.js index 4922bf6..2f041d9 100644 --- a/run.js +++ b/run.js @@ -14,8 +14,6 @@ const log = (level,msg) => console.log(`\x1b[33m[${level}]\x1b[0m ${msg}`) const { name, version, browserslist: browserlistString } = JSON.parse(await readFile('./package.json')) const comment = `/*! ${name}.js ${version} */` -let seen = new Set() -fs.writeFileSync('output.txt', JSON.stringify(compat.configs['flat/recommended'], (key, value) => (typeof value === 'object' && seen.has(value)) ? undefined : (seen.add(value), value), 2), seen = new Set()) const filenames = { css: 'biscuitman.css', minCss: 'biscuitman.min.css', @@ -194,7 +192,7 @@ export async function report() { } export async function jsreport() { - // TODO: This doesn't work + // TODO: This doesn't work, rip it out log('js report','Checking JS browser compatibility...') let js = await scripts(true) const eslint = new ESLint({ @@ -263,7 +261,7 @@ export async function serve() { bs.watch('./src/biscuitman.js', async (event, file) => { if (event === 'change') { console.log(`${file} has changed`) - await scripts() + await build() bs.reload() } }) @@ -279,10 +277,10 @@ export async function serve() { server: './', files: ['./dist/*','index.html','./src/*.css','./src/*.js', './src/*.mjs'], // watch port: 3000, - https: { // required for https cookies - key: './server.key', - cert: './server.crt' - }, + // https: { // required for https cookies + // key: './server.key', + // cert: './server.crt' + // }, open: false, notify: false }) diff --git a/src/biscuitman.css b/src/biscuitman.css index 3f989a7..dec4cd4 100644 --- a/src/biscuitman.css +++ b/src/biscuitman.css @@ -1,4 +1,4 @@ -/* +/* Biscuitman JS Styles https://github.com/replete/biscuitman @@ -23,7 +23,7 @@ z-index: 3; display:none; - html.bm-show & { + .bm-show & { display:block } @@ -176,7 +176,7 @@ margin-bottom: -24px; width: 100%; height: 25px; - background: linear-gradient(180deg, var(--bg) 20%, transparent); + background: linear-gradient(180deg, var(--bg) 20%, rgba(255,255,255,0)); /* rgba is safari < 15 fix */ pointer-events: none; z-index: 1; } @@ -188,7 +188,7 @@ top: -24px; width: 100%; height: 25px; - background: linear-gradient(0deg, var(--bg) 20%, transparent); + background: linear-gradient(0deg, var(--bg) 20%, rgba(255,255,255,0)); /* rgba is safari < 15 fix */ pointer-events: none; } } @@ -377,3 +377,10 @@ } } } + +/* https://github.com/GoogleChrome/dialog-polyfill?tab=readme-ov-file#stacking-context */ +.bm-dialog-polyfill .biscuitman dialog { + position:fixed; + top:50%; + transform: translateY(-50%); +} diff --git a/src/biscuitman.js b/src/biscuitman.js index 126c097..2587073 100644 --- a/src/biscuitman.js +++ b/src/biscuitman.js @@ -16,6 +16,7 @@ more: 'Show more', noCookies: 'No cookies to display', acceptNonEU: false, + dialogPolyfillUrl: '//cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.5.6/dialog-polyfill.min.js' // message: 'By clicking "Accept All", you agree to the use of cookies for improving browsing, providing personalized ads or content, and analyzing traffic. {link}', // info: `Cookies categorized as "Essential" are stored in your browser to enable basic site functionalities. // Additionally, third-party cookies are utilized to analyze website usage, store preferences, and deliver relevant content and advertisements with your consent. @@ -39,6 +40,7 @@ // advertisementMessage: 'Advertisement cookies serve to deliver tailored advertisements to visitors based on their previous page visits and to evaluate the efficacy of advertising campaigns', // uncategorizedTitle: 'Uncategorized', // uncategorizedMessage: 'Uncategorized cookies are those currently under analysis and have not yet been assigned to a specific category', + } const o = { ...defaults, ...w.biscuitman } @@ -103,6 +105,7 @@ `.replaceAll('{link}',`${o.linkText}`) ui.querySelectorAll('button').forEach(b => b.addEventListener('click', buttonHandler)) dialog = ui.querySelector('dialog') + if (!dialog.showModal || !dialog.close) loadDialogPolyfill() dialog.addEventListener('close', closeModalHandler) dialog.addEventListener('cancel', cancelModalHandler) const moreLink = ui.querySelector('.more') @@ -249,7 +252,7 @@ dispatch('save', { data: consents }) clearStorages() insertScripts() - dialog.close() + if (dialog.open) dialog.close() displayUI(false) } @@ -322,4 +325,21 @@ dispatch('update', { data: getConsents() }) openModal() } + + function loadDialogPolyfill() { + // https://github.com/GoogleChrome/dialog-polyfill + h.classList.add('bm-dialog-polyfill') + const script = d.createElement('script') + script.src = o.dialogPolyfillUrl + script.onload = () => { + w.dialogPolyfill.registerDialog(dialog) + } + d.head.appendChild(script) + + const link = d.createElement('link') + link.rel = 'stylesheet' + link.href = o.dialogPolyfillUrl.slice(0,-2) + 'css' + d.head.appendChild(link) + } + })(document, window, Object, document.documentElement, 'biscuitman') diff --git a/src/biscuitman.mjs b/src/biscuitman.mjs index b930790..4602d57 100644 --- a/src/biscuitman.mjs +++ b/src/biscuitman.mjs @@ -23,6 +23,7 @@ const defaults = { more: 'Show more', noCookies: 'No cookies to display', acceptNonEU: false, + dialogPolyfillUrl: '//cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.5.6/dialog-polyfill.min.js' // message: 'By clicking "Accept All", you agree to the use of cookies for improving browsing, providing personalized ads or content, and analyzing traffic. {link}', // info: `Cookies categorized as "Essential" are stored in your browser to enable basic site functionalities. // Additionally, third-party cookies are utilized to analyze website usage, store preferences, and deliver relevant content and advertisements with your consent. @@ -109,6 +110,7 @@ function render() { `.replaceAll('{link}',`${options.linkText}`) ui.querySelectorAll('button').forEach(b => b.addEventListener('click', buttonHandler)) dialog = ui.querySelector('dialog') + if (!dialog.showModal || !dialog.close) loadDialogPolyfill() dialog.addEventListener('close', closeModalHandler) dialog.addEventListener('cancel', cancelModalHandler) const moreLink = ui.querySelector('.more') @@ -258,7 +260,7 @@ function saveConsents(value) { dispatch('save', { data: consents }) clearStorages() insertScripts() - dialog.close() + if (dialog.open) dialog.close() displayUI(false) } @@ -297,6 +299,22 @@ function handleNonEUConsent() { } } +function loadDialogPolyfill() { + // https://github.com/GoogleChrome/dialog-polyfill + h.classList.add('bm-dialog-polyfill') + const script = d.createElement('script') + script.src = options.dialogPolyfillUrl + script.onload = () => { + w.dialogPolyfill.registerDialog(dialog) + } + d.head.appendChild(script) + + const link = d.createElement('link') + link.rel = 'stylesheet' + link.href = options.dialogPolyfillUrl.slice(0,-2) + 'css' + d.head.appendChild(link) +} + function create(config = {}) { if (instance) return instance @@ -342,6 +360,7 @@ function create(config = {}) { openModal() } + initialize() instance = {