Skip to content

Commit 083949c

Browse files
authored
Merge pull request #1 from thoughtco/feature/move-all-cookie-handling-to-js
Switch to using JS for all consent settings
2 parents de78e58 + 3f6c5a9 commit 083949c

File tree

5 files changed

+126
-125
lines changed

5 files changed

+126
-125
lines changed

resources/js/cookiepanel.js

Lines changed: 99 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,150 @@
1-
window.addEventListener('DOMContentLoaded', function(){
1+
window.addEventListener('DOMContentLoaded', () => {
22

3-
// Detect if user is on IE browser
4-
var isIE = !!window.MSInputMethodContext && !!document.documentMode;
5-
6-
// ie requires promise + fetch polyfills
7-
if (isIE) {
8-
var promiseScript = document.createElement("script");
9-
promiseScript.type = "text/javascript";
10-
promiseScript.src =
11-
"https://cdn.jsdelivr.net/npm/promise-polyfill@8.1.3/dist/polyfill.min.js";
3+
const ConsentPanel = class {
4+
constructor(el) {
5+
if (! el) {
6+
console.error('Consent panel element not found');
7+
return;
8+
}
129

13-
var fetchScript = document.createElement("script");
14-
fetchScript.type = "text/javascript";
15-
fetchScript.src =
16-
"https://cdn.jsdelivr.net/npm/whatwg-fetch@3.4.0/dist/fetch.umd.min.js";
10+
this.panelElement = el;
1711

18-
document.head.appendChild(promiseScript);
19-
document.head.appendChild(fetchScript);
20-
}
12+
this.panelElement.addEventListener('click', this.clickAndInputHandler.bind(this));
2113

22-
var cookiePanel;
23-
if (cookiePanel = document.querySelector('.thoughtco-cookiepanel')) {
14+
let selectedCategories = this.getConsentSettings();
2415

25-
var clickAndInputHandler = function(event) {
16+
[].forEach.call(this.panelElement.querySelectorAll('input[type="checkbox"]'), (el) => {
17+
if (selectedCategories.includes(el.value)) {
18+
el.checked = true;
19+
}
20+
});
2621

27-
var target = event.target;
22+
if (! selectedCategories.length) {
23+
this.panelElement.classList.add('open');
24+
}
2825

29-
// if we are a checkbox
30-
if (target.closest('.toggler')) {
31-
return;
26+
if (! selectedCategories.includes('functional')) {
27+
selectedCategories.push('functional');
3228
}
3329

34-
var categoryEls = cookiePanel.querySelectorAll('input[type="checkbox"]');
30+
this.updateScriptConsent(selectedCategories);
31+
}
3532

36-
var attr = target.getAttribute('data-cookiepanel');
33+
clickAndInputHandler (event) {
34+
let categoryEls = this.panelElement.querySelectorAll('input[type="checkbox"]');
35+
36+
let attr = event.target.getAttribute('data-consentpanel');
3737
if (!attr) {
3838
return;
3939
}
4040

41-
var autoClose = false;
41+
if (event.target.tagName.toLowerCase() == 'input') {
42+
return;
43+
}
44+
45+
let autoClose = false;
4246
switch (attr) {
4347
case 'open':
44-
cookiePanel.classList.add('open');
48+
this.panelElement.classList.add('open');
4549
return;
4650
break;
4751

4852
case 'close':
49-
cookiePanel.classList.remove('open');
53+
this.panelElement.classList.remove('open');
54+
return;
5055
break;
5156

5257
case 'reject':
53-
for (var i=0; i<categoryEls.length; i++)
58+
for (let i=0; i<categoryEls.length; i++) {
5459
categoryEls[i].checked = false;
60+
}
5561

5662
autoClose = true;
5763
break;
5864

5965
case 'accept':
60-
for (var i=0; i<categoryEls.length; i++)
66+
for (let i=0; i<categoryEls.length; i++) {
6167
categoryEls[i].checked = true;
68+
}
69+
70+
autoClose = true;
71+
break;
6272

73+
case 'select':
6374
autoClose = true;
6475
break;
6576
}
6677

67-
var selectedCategories = [];
68-
for (var i=0; i<categoryEls.length; i++) {
78+
let selectedCategories = [];
79+
for (let i=0; i<categoryEls.length; i++) {
6980
if (categoryEls[i].checked) {
7081
selectedCategories.push(categoryEls[i].value);
7182
}
7283
}
7384

74-
var data = new FormData();
75-
data.append('_token', cookiePanel.querySelector('[name="_token"]').value);
76-
data.append('categories', selectedCategories.join(','));
77-
78-
fetch('/!/statamic-cookiepanel', {
79-
method: 'POST',
80-
body: data,
81-
headers: {
82-
'X-Requested-With': 'XMLHttpRequest'
83-
},
84-
});
85+
localStorage.setItem('consent_settings', selectedCategories.join(','));
8586

8687
if (autoClose) {
87-
cookiePanel.classList.remove('open');
88+
this.panelElement.classList.remove('open');
8889
}
8990

90-
window.dispatchEvent(new CustomEvent('statamic-cookiepanel:consent-changed', {
91+
this.updateScriptConsent(selectedCategories);
92+
93+
window.dispatchEvent(new CustomEvent('statamic-consentpanel:consent-changed', {
9194
detail: {
9295
categories: selectedCategories,
9396
}
9497
}));
95-
};
98+
}
99+
100+
getConsentSettings() {
101+
return localStorage.getItem('consent_settings')?.split(',') ?? [];
102+
}
103+
104+
hasConsentedTo(category) {
105+
return this.getConsentSettings().includes(category);
106+
}
107+
108+
updateScriptConsent(categories) {
109+
[].forEach.call(document.querySelectorAll('[data-consentpanel-type]'), (el) => {
110+
let id = el.getAttribute('data-consentpanel-id');
111+
112+
if (! id) {
113+
return;
114+
}
115+
116+
// consented
117+
if (categories.includes(el.getAttribute('data-consentpanel-type'))) {
118+
if (! document.querySelector('[data-consentpanel-output="' + id + '"]')) {
119+
let div = document.createElement('div');
120+
div.innerHTML = el.innerHTML;
121+
122+
let fragment = document.createDocumentFragment();
96123

97-
cookiePanel.addEventListener('click', clickAndInputHandler);
98-
}
124+
for (const child of div.children) {
125+
let newChild = document.createRange().createContextualFragment(child.outerHTML);
126+
fragment.appendChild(newChild);
127+
}
128+
129+
for (const child of fragment.children) {
130+
child.setAttribute('data-consentpanel-output', id);
131+
}
132+
133+
el.parentNode.appendChild(fragment);
134+
}
135+
136+
return;
137+
}
138+
139+
// not consented
140+
if (document.querySelector('[data-consentpanel-output="' + id + '"]')) {
141+
[].forEach.call(document.querySelectorAll('[data-consentpanel-output="' + id + '"]'), (el) => {
142+
el.parentNode.removeChild(el);
143+
});
144+
}
145+
});
146+
}
147+
};
99148

149+
window.ConsentPanel = new ConsentPanel(document.querySelector('.thoughtco-cookiepanel'));
100150
});

resources/views/panel.blade.php

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,38 @@
1-
<div class="thoughtco-cookiepanel @if($openPanel) open @endif">
2-
@csrf
3-
<button class="cookiepanel-open" data-cookiepanel="open">{{ $data['button_text'] }}</button>
1+
<div class="thoughtco-cookiepanel">
2+
<button class="cookiepanel-open" data-consentpanel="open">{{ $data['button_text'] }}</button>
43
<div class="cookiepanel-overlay"></div>
54
<div class="cookiepanel-sidebar">
6-
7-
<button type="button" class="cookiepanel-close" data-cookiepanel="close">Close</button>
8-
5+
6+
<button type="button" class="cookiepanel-close" data-consentpanel="close">Close</button>
7+
98
{!! $data['introduction'] !!}
10-
11-
<div class="buttons">
12-
<button type="button" data-cookiepanel="accept">Accept all</button>
13-
@php $rejectShown = false; @endphp
14-
@foreach ($data['cookie_groups'] as $group)
15-
@if (!$rejectShown && $group['enabled'] && $group['show_toggle'])
16-
<button type="button" data-cookiepanel="reject">Reject all</button>
17-
@php $rejectShown = true; @endphp
18-
@endif
19-
@endforeach
20-
</div>
21-
9+
2210
@foreach ($data['cookie_groups'] as $group)
2311
@if ($group['enabled'])
2412
<p class="heading">{{ $group['title'] }}</p>
2513
<p>{{ $group['description'] }}</p>
26-
14+
2715
@if ($group['show_toggle'])
2816
<div class="toggler">
29-
<input type="checkbox" data-cookiepanel="category" value="{{ $group['slug'] }}" id="thoughtco-cookiepanel-{{ $loop->index }}" @if(in_array($group['slug'], $cookie)) checked @endif />
17+
<input type="checkbox" data-consentpanel="category" value="{{ $group['slug'] }}" id="thoughtco-cookiepanel-{{ $loop->index }}" />
3018
<label for="thoughtco-cookiepanel-{{ $loop->index }}">Enabled</label>
3119
<label for="thoughtco-cookiepanel-{{ $loop->index }}">Disabled</label>
3220
</div>
33-
@endif
34-
@endif
35-
@endforeach
21+
@endif
22+
@endif
23+
@endforeach
24+
25+
<div class="buttons">
26+
<button type="button" data-consentpanel="accept">Accept all</button>
27+
@php $rejectShown = false; @endphp
28+
@foreach ($data['cookie_groups'] as $group)
29+
@if (!$rejectShown && $group['enabled'] && $group['show_toggle'])
30+
<button type="button" data-consentpanel="select">Accept Selected</button>
31+
<button type="button" data-consentpanel="reject">Reject all</button>
32+
@php $rejectShown = true; @endphp
33+
@endif
34+
@endforeach
35+
</div>
3636

3737
</div>
38-
</div>
38+
</div>

src/Http/Controllers/CookiePanelController.php

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/ServiceProvider.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,6 @@ public function boot()
2727
{
2828
parent::boot();
2929

30-
// handle the posting of the cookie
31-
Statamic::booted(function () {
32-
$this->registerActionRoutes(function () {
33-
Route::post('/', [CookiePanelController::class, 'index']);
34-
});
35-
});
36-
3730
// after install we need to copy our global
3831
Statamic::afterInstalled(function ($command) {
3932

src/Tags/CookiePanel.php

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,15 @@ class CookiePanel extends Tags
1515
*/
1616
public function panel()
1717
{
18-
if (Request::hasHeader('X-Statamic-Live-Preview'))
18+
if (Request::hasHeader('X-Statamic-Live-Preview')) {
1919
return '';
20-
21-
$cookie = Request::cookie('tc_cookie_policy', false);
20+
}
2221

2322
$panelData = GlobalSet::findByHandle('cookie_panel')
2423
->inCurrentSite()
2524
->data();
2625

2726
return view('statamic-cookiepanel::panel', [
28-
'openPanel' => $cookie === false,
29-
'cookie' => $cookie === false ? [] : json_decode($cookie),
3027
'data' => $panelData,
3128
]);
3229
}
@@ -72,20 +69,6 @@ public function cookieTable()
7269
*/
7370
public function hasConsentedTo()
7471
{
75-
$cookie = Request::cookie('tc_cookie_policy', false);
76-
77-
// we don't have the cookie policy
78-
if (!$cookie)
79-
return false;
80-
81-
$type = $this->params->get('type', 'functional');
82-
83-
$consentedTo = json_decode($cookie);
84-
85-
// if we have none then we dont consent
86-
if (in_array('none', $consentedTo))
87-
return false;
88-
89-
return in_array($type, $consentedTo);
72+
return '<template data-consentpanel-type="'.$this->params->get('type', 'functional').'" data-consentpanel-id="'.uniqid().'">'.$this->parse().'</template>';
9073
}
9174
}

0 commit comments

Comments
 (0)