Verified Commit 3bf0f9ca authored by Laurent Heirendt's avatar Laurent Heirendt
Browse files

Merge branch 'add-gdpr-version2' into add-gdpr

parents ac136556 067c17d5
......@@ -84,18 +84,20 @@ kramdown:
# parse_block_html: true
# GDPR banner settings
banner_title: >-
This website uses cookies
banner_text: >-
This website needs some cookies and similar means to function.<br>
If you permit us, we will use those means to collect data on your visits for aggregated statistics to improve our service.
banner_accept_text: >-
Accept cookies for anonymized aggregated statistics
Accept
banner_refuse_text: >-
No thanks, only technically necessary cookies
No thanks
banner_more_text: >-
More information
cookies_expire: 180 # days
analyticsurl: https://analytics.lcsb.uni.lu/hub/
siteID: 4 # you get this siteID by sending an email to lcsb-r3@uni.lu
cookieName: lap
accept_all_text: >-
Aggregate statistics cookies accepted
only_necessary_text: >-
......
<div id="lap-cookies-banner">
<div class="banner-text">{{ site.banner_text }}</div>
<div class="banner-intro">
<div class="banner-img">
<img src="{{ '/assets/banners/r3-logo.svg' | relative_url }}" type="image/svg+xml" />
</div>
<div class="banner-title">{{ site.banner_title }}</div>
<div class="banner-text">{{ site.banner_text }}</div>
</div>
<div class="banner-checkboxes">
<label class="input-toggle">
<input type="checkbox" checked disabled>
<span></span>
</label>
<span class="checkbox-label">Necessary</span>
<label class="input-toggle analytics">
<input id="checkbox-1" type="checkbox">
<span></span>
</label>
<span class="checkbox-label">Analytics</span>
</div>
<div class="banner-buttons">
<a class="btn lap-cookies-accept" href="">{{ site.banner_accept_text }}</a>
<a class="btn lap-cookies-refuse" href="">{{ site.banner_refuse_text }}</a>
<a class="btn lap-accept">{{ site.banner_accept_text }}</a>
<a class="btn lap-refuse">{{ site.banner_refuse_text }}</a>
<a class="btn lap-cookies-more" href="{{ site.path_policy }}">{{ site.banner_more_text }}</a>
</div>
</div>
\ No newline at end of file
......@@ -26,10 +26,12 @@
settings.siteID = "{{ site.siteID }}";
settings.accept_all_text = "{{ site.accept_all_text }}"
settings.only_necessary_text = "{{ site.only_necessary_text }}"
settings.cookieName = "{{ site.cookieName }}"
settings.bots = /bot|crawler|spider|crawling/i;
</script>
<script src="{{ '/assets/js/jquery.min.js' | relative_url }}"></script>
<script src="{{ '/assets/js/js.cookie.min.js' | relative_url }}"></script>
<script src="{{ '/assets/js/gdpr.js' | relative_url }}"></script>
{%- endif -%}
{%- if jekyll.environment == "review" -%}
......@@ -42,4 +44,4 @@
src='{{site.gitlab_host}}/assets/webpack/visual_review_toolbar.js'></script>
{%- endif -%}
</head>
</head>
\ No newline at end of file
<p>
<a href="privacyPolicy">Privacy Policy</a>
(<span id="gdpr-result-text"></span> - <a href="javascript: showCookieBanner();">change</a>)
</p>
(<span id="gdpr-result-text"></span> - <a href="javascript: showBanner();">change</a>)
</p>
\ No newline at end of file
......@@ -2,7 +2,3 @@
Add here additional javascript libraries and code.
Uncomment those if needed.
{% endcomment %}
{% comment %}
<script src="{{ '/assets/js/bootstrap.min.js' | relative_url }}" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
{% endcomment %}
\ No newline at end of file
......@@ -9,25 +9,48 @@
text-align: center;
border-top: 1px solid #198cdc;
width: 100%;
display: none; /* hidden by default */
display: none;
/* hidden by default */
}
#lap-cookies-banner .banner-intro {
width: 40%;
position: relative;
left: 30%;
text-align: left;
}
#lap-cookies-banner .banner-img {
width: 50px;
position: absolute;
padding-top: 5px;
height: 50px;
}
#lap-cookies-banner .banner-title {
font-size: 120%;
font-weight: bold;
text-align: left;
padding-left: 60px;
}
#lap-cookies-banner .banner-text {
float: center;
min-height: 60px;
padding-left: 40px;
padding-right: 40px;
float: center;
min-height: 40px;
padding-left: 60px;
font-size: 80%;
text-align: left;
}
#lap-cookies-banner .banner-buttons {
float: center;
line-height: 54px;
}
#lap-cookies-banner .banner-buttons .lap-cookies-accept,
#lap-cookies-banner .banner-buttons .lap-cookies-refuse,
#lap-cookies-banner .banner-buttons .lap-accept,
#lap-cookies-banner .banner-buttons .lap-refuse,
#lap-cookies-banner .banner-buttons .lap-cookies-more,
#lap-cookies-banner .banner-buttons .btn.active {
margin: 0.3rem 0.5rem;
text-decoration: none;
padding: 10px 25px;
border: 1px solid #198cdc;
font-weight: bold;
background-color: #198cdc;
......@@ -36,10 +59,11 @@
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
#lap-cookies-banner .banner-buttons .lap-cookies-accept:hover,
#lap-cookies-banner .banner-buttons .lap-cookies-refuse:hover,
#lap-cookies-banner .banner-buttons .lap-accept:hover,
#lap-cookies-banner .banner-buttons .lap-refuse:hover,
#lap-cookies-banner .banner-buttons .lap-cookies-more:hover,
#lap-cookies-banner .banner-buttons .btn.disabled {
#lap-cookies-banner .banner-buttons .btn.selected {
background: white;
color: #198cdc !important;
border: 1px solid #198cdc;
......@@ -48,7 +72,9 @@
-webkit-box-sizing: border-box;
text-decoration: none;
}
#lap-cookies-banner .btn {
text-decoration: none;
display: inline-block;
margin-bottom: 0;
text-align: center;
......@@ -56,11 +82,109 @@
touch-action: manipulation;
background-image: none;
white-space: nowrap;
padding: 6px 12px;
font-size: 14px;
padding: 3px 10px;
font-size: 9pt;
line-height: 1.43;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
// Small component to show a Material Design style input toggle
// ref: https://codepen.io/FezVrasta/pen/yNRgrB - MIT licensed
$toggle-w: 32px;
$toggle-h: 14px;
$handle-size: 18px;
$unchecked-handle-bg: #F1F1F1;
$checked-handle-bg: #198cdc;
$disabled-handle-bg: #BDBDBD;
$unchecked-toggle-bg: #848484;
$checked-toggle-bg: desaturate(lighten($checked-handle-bg, 28%), 32%); // kind of magic recipe
$disabled-toggle-bg: #D5D5D5;
label.input-toggle {
line-height: 0;
font-size: 0;
display: inline-block;
margin: 0;
>span {
display: inline-block;
position: relative;
background-image: linear-gradient( to right, $unchecked-toggle-bg 0%, $unchecked-toggle-bg 50%, $checked-toggle-bg 50%, $checked-toggle-bg 100%);
background-size: $toggle-w*2 $toggle-h;
background-position: 0%;
border-radius: $toggle-w;
width: $toggle-w;
height: $toggle-h;
cursor: pointer;
transition: background-position 0.2s ease-in;
}
>input:checked+span {
background-position: -100%;
}
>span:after {
content: "";
display: block;
position: absolute;
width: $handle-size;
height: $handle-size;
background: $unchecked-handle-bg;
align-self: center;
top: 50%;
left: 0;
transform: translateY(-50%);
border-radius: 100%;
//box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
transition: left 0.2s ease-in, background-color 0.2s ease-in, transform 0.3s ease;
}
>input:checked+span:after {
left: $handle-size;
background-color: $checked-handle-bg;
}
// Jelly effect on click
>span:active:after {
//transform: translateY(-50%) scale3d(1.15, 0.85, 1);
}
// No jelly effect on disabled toggles
>input:disabled+span:active:after {
transform: translateY(-50%);
}
>input:disabled+span {
cursor: default;
}
>input:disabled+span {
background: $disabled-toggle-bg;
}
>input:disabled+span:after {
background: $disabled-handle-bg;
}
// Hide original checkbox, but don't use `display: none` to allow focus on it using keyboard
>input {
display: block;
position: absolute;
opacity: 0;
width: 0;
height: 0;
}
}
#lap-cookies-banner .banner-checkboxes {
font-size: 80%;
margin-top: 1em;
}
#lap-cookies-banner .checkbox-label {
margin-left: 0.3em;
margin-right: 1.5em;
top: -0.2em;
position: relative;
}
@media(max-width: 1100px) {
#lap-cookies-banner .banner-intro {
width: 90%;
position: relative;
left: 5%;
text-align: left;
}
}
\ No newline at end of file
This diff is collapsed.
/* Matomo global variable
note: most code has been inspired from:
https://edps.europa.eu/sites/edp/modules/features/edpsweb_cookies/js/cookies-popup.js
*/
var _paq = window._paq || _paq || [];
/* loadMatomo: load the tracking code of the matomo instance */
// convert days to milliseconds
settings.cookieTimeout = settings.expires * 86400 * 1000;
/*
* loadMatomo: load the tracking code of the analytics instance
*/
function loadMatomo() {
if (settings.siteID > 0) {
var u = settings.matomoURL;
......@@ -15,106 +15,196 @@ function loadMatomo() {
_paq.push(['trackPageView']);
_paq.push(['setIgnoreClasses', ['no-tracking', 'colorbox']]);
_paq.push(['enableLinkTracking']);
var d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
var d = document,
g = d.createElement('script'),
s = d.getElementsByTagName('script')[0];
g.type = 'text/javascript';
g.defer = true;
g.async = true;
g.src = u + 'matomo.js';
s.parentNode.insertBefore(g,s);
s.parentNode.insertBefore(g, s);
setResultText(true);
}
}
function setResultText(acceptCookies){
if (acceptCookies == true) {
/*
* setResultText: change the text in the footer
*/
function setResultText(acceptCookies) {
if (acceptCookies === true) {
$('#gdpr-result-text').html(settings.accept_all_text);
} else {
$('#gdpr-result-text').html(settings.only_necessary_text);
}
}
/* showCookieBanner: show the banner */
function showCookieBanner() {
var popup = jQuery('#lap-cookies-banner');
popup.hide();
popup.slideDown('slow');
/*
* showBanner: show the banner
*/
function showBanner() {
var popup = $('#lap-cookies-banner');
popup.hide();
popup.slideDown('slow');
}
/* hideCookieBanner: show the banner */
function hideCookieBanner() {
var popup = jQuery('#lap-cookies-banner');
popup.hide();
/*
* hideBanner: show the banner
*/
function hideBanner() {
var popup = $('#lap-cookies-banner');
setTimeout(() => { popup.slideUp('slow'); }, 1200);
}
/* clearCookies: clear all cookies */
/*
* clearCookies: clear all cookies
*/
function clearCookies() {
var cookies = document.cookie.split('; ');
var originOfTime = new Date(0);
var hostname = document.location.hostname.replace(/^www\./, ''),
commonSuffix = '; expires= ' + originOfTime + '; path=/';
// remove the analytics cookies
var cookies = document.cookie.split('; ');
for (var i in cookies) {
var name = cookies[i].split('=')[0];
if (name.startsWith('_pk_')) {
Cookies.set(name, 0, { expires: -1, path: '/' });
}
var name = cookies[i].split('=')[0];
if (name.startsWith('_pk_') || name.startsWith('MATOMO_SESSID')) {
document.cookie = name + '=; ' + commonSuffix;
}
}
setResultText(false);
}
$( document ).ready(function() {
/* accept */
$('.lap-cookies-accept').click(function (e) {
e.preventDefault(true);
Cookies.set('lap_cookie_agree', 1, { expires: parseInt(settings.expires), path: '/' });
hideCookieBanner();
jQuery('.lap-cookies-accept').addClass('disabled');
jQuery('.lap-cookies-refuse').removeClass('disabled');
jQuery(this).blur();
/*
* setCookie: create/update cookie
*/
function setCookie(name, value) {
var date = new Date();
date.setTime(date.getTime() + settings.cookieTimeout);
loadMatomo();
document.cookie = name + '=' + value + ';expires=' + date.toGMTString() + ';path=/';
}
function isCookieSetTo(val) {
return document.cookie.indexOf(settings.cookieName + '=' + val) > -1;
}
/*
* hasConsent: check if user gave consent
*/
function hasConsent() {
if (isCookieSetTo(1)) {
setResultText(true);
return true;
} else if (isCookieSetTo(0)) {
setResultText(false);
return false;
}
return null;
}
/*
* accept: accept the cookies
*/
function accept() {
// action
loadMatomo();
// cookie management
setCookie(settings.cookieName, 1);
// feedback
setResultText(true);
// style
$('.lap-accept').addClass('selected');
$('.lap-refuse').removeClass('selected');
$("input[id^=check]").not(this).prop('checked', true);
}
/*
* accept: refuse the cookies
*/
function refuse(doNotTrack) {
// action
clearCookies();
// cookie management
// only set the refusal cookie if actually allowed (i.e. doNotTrack = false)
if (doNotTrack === false) {
setCookie(settings.cookieName, 0);
}
// feedback
setResultText(false);
// style
$('.lap-refuse').addClass('selected');
$('.lap-accept').removeClass('selected');
$("input[id^=check]").not(this).prop('checked', false);
}
/*
* toggleBox: refuse/accept based on checkbox with boxID
*/
function toggleBox(boxID) {
if ($('input#checkbox-' + boxID)[0].checked === true) {
refuse(false);
} else {
accept();
}
hideBanner();
}
/*
* main function
*/
$(document).ready(function() {
// accept
$('.lap-accept').click(function(e) {
e.preventDefault(true);
accept();
hideBanner();
});
/* refuse */
$('.lap-cookies-refuse').click(function (e) {
// refuse
$('.lap-refuse').click(function(e) {
e.preventDefault(true);
clearCookies();
Cookies.set('lap_cookie_agree', 0, { expires: parseInt(settings.expires), path: '/' });
hideCookieBanner();
jQuery('.lap-cookies-refuse').addClass('disabled');
jQuery('.lap-cookies-accept').removeClass('disabled');
jQuery(this).blur();
setResultText(false);
refuse(false);
hideBanner();
});
/* default mechanism */
dnt = false;
if (window.doNotTrack || navigator.doNotTrack || navigator.msDoNotTrack || ('external' in window && 'msTrackingProtectionEnabled' in window.external)) {
if (window.doNotTrack == "1" || navigator.doNotTrack == "yes" || navigator.doNotTrack == "1" || navigator.msDoNotTrack == "1" || ('external' in window && 'msTrackingPronectionEnabled' in window.external && window.external.msTrackingProtectionEnabled())) {
/* Do Not Track is enabled => stop */
jQuery('.lap-cookies-accept, .lap-cookies-refuse').addClass('disabled');
dnt = true;
}
}
if (dnt == false) {
// get the indicator cookie
var lapCookieAgree = '';
var name = 'lap_cookie_agree=';
var cookieArray = decodeURIComponent(document.cookie).split('; ');
cookieArray.forEach(cookie => {
if (cookie.indexOf(name) == 0) {
lapCookieAgree = cookie.substring(name.length, cookie.length);
}
});
// logic
if (lapCookieAgree == '0') {
/* visitor refused cookies => remove Matomo trace if present */
jQuery('.lap-cookies-refuse').addClass('disabled');
clearCookies();
} else if (lapCookieAgree == '1') {
/* visitor accepted cookies => load Matomo */
jQuery('.lap-cookies-accept').addClass('disabled');
loadMatomo();
} else {
/* visitor did not choose yet */
showCookieBanner();
$('.analytics').click(function(e) {
e.preventDefault(true);
toggleBox(1); // this ID matches with the checkbox-1 input
});
// detect if the visitor is a bot or not
// prevent search engine t otake the cookie alert message as main content
var isBot = settings.bots.test(navigator.userAgent);
// check if DoNotTrack is active
var dnt = navigator.doNotTrack || navigator.msDoNotTrack || window.doNotTrack;
var isToTrack = (dnt !== null && dnt !== undefined) ? (dnt && dnt !== 'yes' && dnt !== 1 && dnt !== '1') : true;
var doNotTrack = false;
// do nothing if it is a bot or if DoNotTrack is active
if (isBot || !isToTrack || hasConsent() === false) {
doNotTrack = true;
refuse(doNotTrack);
hideBanner();
}
if (doNotTrack === false) {
if (hasConsent() === true) {
// user has already given consent to use cookies to tracking
accept();
hideBanner();
} else if (hasConsent() === false || hasConsent() === null) {
// all other cases considered, show banner
showBanner();
}
}
});
\ No newline at end of file
/*! js-cookie v3.0.0-rc.0 | MIT */
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self,function(){var r=e.Cookies,n=e.Cookies=t();n.noConflict=function(){return e.Cookies=r,n}}())}(this,function(){"use strict";function e(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)e[n]=r[n]}return e}var t={read:function(e){return e.replace(/%3B/g,";")},write:function(e){return e.replace(/;/g,"%3B")}};return function r(n,i){function o(r,o,u){if("undefined"!=typeof document){"number"==typeof(u=e({},i,u)).expires&&(u.expires=new Date(Date.now()+864e5*u.expires)),u.expires&&(u.expires=u.expires.toUTCString()),r=t.write(r).replace(/=/g,"%3D"),o=n.write(String(o),r);var c="";for(var f in u)u[f]&&(c+="; "+f,!0!==u[f]&&(c+="="+u[f].split(";")[0]));return document.cookie=r+"="+o+c}}return Object.create({set:o,get:function(e){if("undefined"!=typeof document&&(!arguments.length||e)){for(var r=document.cookie?document.cookie.split("; "):[],i={},o=0;o<r.length;o++){var u=r[o].split("="),c=u.slice(1).join("="),f=t.read(u[0]).replace(/%3D/g,"=");if(i[f]=n.read(c,f),e===f)break}return e?i[e]:i}},remove:function(t,r){o(t,"",e({},r,{expires:-1}))},withAttributes:function(t){return r(this.converter,e({},this.attributes,t))},withConverter:function(t){return r(e({},this.converter,t),this.attributes)}},{attributes:{value:Object.freeze(i)},converter:{value:Object.freeze(n)}})}(t,{path:"/"})});
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment