Skip to content

Commit 6e61d76

Browse files
committed
Add revoke event. Update CSS. Update README.
- use browserstring in build script - update screenshot
1 parent 2375910 commit 6e61d76

14 files changed

+69
-48
lines changed

README.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,25 @@
33

44
#### [View demo](https://replete.github.io/biscuitman)
55

6-
100kB+ seemed too heavy for a cookie popup so I wrote this. It's currently < 4kB gz/btr, including CSS. It's designed to be as small as possible with an adequate featureset for basic website cookie consent.
6+
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.
77

88
- Stores consent in `localStorage`, exposes in `window.Consent` and through custom events fired on `document`
99
- Handles consent granulated by custom sections (e.g. essential, performance, analytics...)
10-
- Optionally shows user specific cookie details
11-
- Cookies/localstorage items removed on rejection/invalidation, if cookie details added
10+
- Optionally shows user specific cookie (or localStorage item) details
11+
- Cookies/localstorage items removed on rejection/invalidation, if cookie details added
1212
- Fully customizable strings so you can serve localized strings if you want
1313
- Overridable localStorage key, consent global
1414
- Simple flat configuration object
1515
- Injects scripts when granular consent is granted (`<script data-consent="analytics" type="text/plain" src="..."></script>`)
16-
- Injects embedded `<script>` from script tags with `src` properties on onload (tidier markup)
16+
- Injects embedded 'after' `<script>` from script tags with `src` properties on onload (= less markup)
1717
- Mobile-first
1818
- Browser support (targeted via `browserlist` in `package.json` - `>= 2%, last 2 years`):
1919
- Chrome 105+,
2020
- Edge 105+
2121
- Safari 15.4+
2222
- Firefox 121+
23-
- Samsung browser 20+
24-
- run `npm run build report` and view `index.html` to compatibility table. If you need a version to work in older browsers, update the browserlist version and modify the CSS
23+
- see [CSS Feature Compatibility](https://replete.github.io/biscuitman/#browser-support) (uses `cssreport.json` generated by `npm run report`)
24+
- If you need a version to work in older browsers it's possible but requires updating the `browserlist` string in `package.json`, and then rewriting CSS to remove unsupported features, e.g. `:has()`. If this is really important open an issue and we can look at making it more compatible by default.
2525
- 'show more' functionality for long disclaimer text
2626
- include optional link in any text
2727
- CSS classes on `<html>` element for consents
@@ -38,10 +38,10 @@
3838
- add 'data-consent' property with consent section name (e.g. analytics, functional, performance)
3939
-->
4040
<script data-consent="analytics" async src="https://www.googletagmanager.com/gtag/js?id=G-TEST" type="text/plain" id="js-analytics-gtm">
41-
// The contents of this script is injected when the parent script is loaded, for convenience
42-
console.log(google_tag_manager)
41+
// The contents of this script is injected after load, and ajacent to, parent script (convenience)
42+
console.log('GTM loaded:', !!google_tag_manager)
4343
</script>
44-
<script data-consent="analytics" type="text/plain" id="js-analytics-gtm-after">
44+
<script data-consent="analytics" type="text/plain" id="js-analytics-misc">
4545
console.log('This script runs as soon as analytics section consent is granted')
4646
</script>
4747

@@ -146,15 +146,14 @@ html:not(:has(.bm-hide))::after {
146146
}
147147
```
148148
- example usage: `if (Consent.analytics) { doAnalyticsThing() }`
149-
- `bmInvalidate()` – Delete stored consent data and reinstate UI
150-
- `bmOpen()` – Opens My Consent Settings modal
149+
- `bmInvalidate()` – Delete stored consent data and reinstate UI (you might use this in your app code)
150+
- `bmOpen()` – Opens My Consent Settings modal (you might want to link this on your Privacy policy or footer nav)
151151
- example usage: `<a href="javascript:bmOpen();"> Update my consent settings</a>`
152152

153153
## CSS
154154

155-
- `biscuitman` class is used for the main UI
156-
- consents are added to `<html>` with the convention of `bm-{sectionName}` for granted and `bm-no-{sectionName}` for ungranted
157-
- `bm-hide` is used on the UI container
155+
- `biscuitman`, `bm-hide` on UI container
156+
- `bm-{sectionName}`, `bm-no-{sectionName}` on `<html>` for consent state
158157

159158
## Events
160159

@@ -165,6 +164,7 @@ The easiest way to see how events work is to view the `console.debug()` calls in
165164
- `biscuitman:save` => `{data: {consentTime: 1718914784624, advertisement:true, advertisement: fal..}, time: 1718914784624}` consent choice saved
166165
- `biscuitman:inject` => `{el: $Element, parent?: $Element, id?: 'script-id', time: 1718914784624}` script injected to DOM. if parent exists, it's a new tag inserted after a `src` script loaded which also had text content (a 'dependent' script = tidier convenient markup)
167166
- `biscuitman:invalidate` => `{data: {...consentObjectJustDeleted}, time: 1718915128298}` consent invalidated
167+
- `biscuitman:revoke` => `{section: 'analytics', time: 1718914784624}` returns section that was revoked if updated consent changed from true to false
168168
- `biscuitman:update` => `{data: {...currentConsentObject}, time: 1718914784624}` returns current consent object and time
169169
- `biscuitman:delete` => `{localStorage|cookie: 'cookieName', time: 1718914784624}` fires when consent is rejected or invalidated and cookies/localStorage entries are deleted
170170

biscuitman.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@
143143
border-radius:10px;
144144
}
145145
@media (min-width:576px) and (min-height:1134px) {
146-
height:890px; /* KLUDGE: magic number based on 6 sections */
146+
max-height:950px; /* KLUDGE: magic number based on 6 sections */
147147
}
148148

149149
nav {

biscuitman.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,18 @@
165165

166166
// Data:
167167

168-
const setConsents = consents => {
168+
const getConsents = () => w[o.global] || {}
169+
170+
function setConsents(consents) {
169171
w[o.global] = consents
170172
applyCssClasses()
171173
}
172174

173-
const getConsents = () => w[o.global]
175+
function checkConsents(oldConsents, newConsents) {
176+
for (const sectionName in oldConsents)
177+
if (oldConsents[sectionName] && newConsents[sectionName] === false)
178+
dispatch('revoke', {section: sectionName})
179+
}
174180

175181
function loadConsents() {
176182
try {
@@ -235,6 +241,7 @@
235241
consents[section] = sectionConsent
236242
if (!willReadValues) sectionElement.checked = value
237243
})
244+
checkConsents(getConsents(),consents)
238245
setConsents(consents)
239246
localStorage.setItem(o.key, JSON.stringify(consents))
240247
dispatch('save', {data: consents})
@@ -285,7 +292,7 @@
285292
// Render UI
286293
render()
287294

288-
// Wipe matching cookies without consent
295+
// Wipe matching cookies/localStorages without consent
289296
clearStorages()
290297

291298
// Consent logic

cssreport.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

dist/biscuitman.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@
150150

151151
@media (min-width: 576px) and (min-height: 1134px) {
152152
.biscuitman dialog {
153-
height: 890px;
153+
max-height: 950px;
154154
}
155155
}
156156

dist/biscuitman.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,16 @@
146146
console.debug(name, payload);
147147
}
148148
// Data:
149-
const setConsents = (consents)=>{
149+
const getConsents = ()=>w[o.global] || {};
150+
function setConsents(consents) {
150151
w[o.global] = consents;
151152
applyCssClasses();
152-
};
153-
const getConsents = ()=>w[o.global];
153+
}
154+
function checkConsents(oldConsents, newConsents) {
155+
for(const sectionName in oldConsents)if (oldConsents[sectionName] && newConsents[sectionName] === false) dispatch('revoke', {
156+
section: sectionName
157+
});
158+
}
154159
function loadConsents() {
155160
try {
156161
return JSON.parse(localStorage.getItem(o.key));
@@ -214,6 +219,7 @@
214219
consents[section] = sectionConsent;
215220
if (!willReadValues) sectionElement.checked = value;
216221
});
222+
checkConsents(getConsents(), consents);
217223
setConsents(consents);
218224
localStorage.setItem(o.key, JSON.stringify(consents));
219225
dispatch('save', {
@@ -269,7 +275,7 @@
269275
}
270276
// Render UI
271277
render();
272-
// Wipe matching cookies without consent
278+
// Wipe matching cookies/localStorages without consent
273279
clearStorages();
274280
// Consent logic
275281
if (w[o.global].consentTime) {

dist/biscuitman.min.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)