mirror of
https://github.com/CaiJimmy/hugo-theme-stack.git
synced 2025-06-18 20:13:31 +08:00
review code of gdpr banner
This commit is contained in:
parent
081040572a
commit
e89e2d3750
@ -22,3 +22,17 @@ body {
|
||||
scrollbar-color: var(--scrollbar-thumb) transparent;
|
||||
}
|
||||
/**/
|
||||
|
||||
/* scrollbar styles for Chromium */
|
||||
::-webkit-scrollbar {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: var(--scrollbar-thumb);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: transparent;
|
||||
}
|
||||
/**/
|
||||
|
@ -123,7 +123,6 @@
|
||||
}
|
||||
|
||||
.article-page.has-toc {
|
||||
|
||||
.left-sidebar {
|
||||
display: none;
|
||||
}
|
||||
@ -395,6 +394,41 @@
|
||||
}
|
||||
}
|
||||
|
||||
.highlight {
|
||||
background-color: var(--pre-background-color);
|
||||
padding: var(--card-padding);
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
.copyCodeButton {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: initial;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.copyCodeButton {
|
||||
position: absolute;
|
||||
top: calc(var(--card-padding));
|
||||
right: calc(var(--card-padding));
|
||||
background: var(--card-background);
|
||||
border: none;
|
||||
box-shadow: var(--shadow-l2);
|
||||
border-radius: var(--tag-border-radius);
|
||||
padding: 8px 16px;
|
||||
color: var(--card-text-color-main);
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.table-wrapper {
|
||||
padding: 0 var(--card-padding);
|
||||
overflow-x: auto;
|
||||
@ -449,6 +483,7 @@
|
||||
/// Negative margins
|
||||
blockquote,
|
||||
figure,
|
||||
.highlight,
|
||||
pre,
|
||||
.gallery,
|
||||
.video-wrapper,
|
||||
@ -458,30 +493,4 @@
|
||||
margin-right: calc((var(--card-padding)) * -1);
|
||||
width: calc(100% + var(--card-padding) * 2);
|
||||
}
|
||||
|
||||
.highlight {
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
.copyCodeButton {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.copyCodeButton {
|
||||
position: absolute;
|
||||
top: calc(var(--card-padding));
|
||||
right: 0;
|
||||
background: var(--card-background);
|
||||
border: none;
|
||||
box-shadow: var(--shadow-l2);
|
||||
border-radius: var(--tag-border-radius);
|
||||
padding: 8px 16px;
|
||||
color: var(--card-text-color-main);
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,6 @@
|
||||
$defaultTagBackgrounds: #8ea885, #df7988, #0177b8, #ffb900, #6b69d6;
|
||||
$defaultTagColors: #fff, #fff, #fff, #fff, #fff;
|
||||
|
||||
[data-scheme="light"] {
|
||||
--pre-text-color: #272822;
|
||||
--pre-background-color: #fafafa;
|
||||
@import "partials/highlight/light.scss";
|
||||
}
|
||||
|
||||
[data-scheme="dark"] {
|
||||
color-scheme: dark;
|
||||
--pre-text-color: #f8f8f2;
|
||||
--pre-background-color: #272822;
|
||||
@import "partials/highlight/dark.scss";
|
||||
}
|
||||
|
||||
/*
|
||||
* Global style
|
||||
*/
|
||||
@ -46,7 +33,7 @@ $defaultTagColors: #fff, #fff, #fff, #fff, #fff;
|
||||
--accent-color-darker: #bdc3c7;
|
||||
--accent-color-text: #000;
|
||||
--body-text-color: rgba(255, 255, 255, 0.7);
|
||||
--scrollbar-thumb: #424242;
|
||||
--scrollbar-thumb: hsl(0, 0%, 40%);
|
||||
--scrollbar-track: var(--body-background);
|
||||
}
|
||||
}
|
||||
@ -160,3 +147,15 @@ $defaultTagColors: #fff, #fff, #fff, #fff, #fff;
|
||||
--shadow-l4: 0px 24px 32px rgba(0, 0, 0, 0.04), 0px 16px 24px rgba(0, 0, 0, 0.04), 0px 4px 8px rgba(0, 0, 0, 0.04),
|
||||
0px 0px 1px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
[data-scheme="light"] {
|
||||
--pre-text-color: #272822;
|
||||
--pre-background-color: #fafafa;
|
||||
@import "partials/highlight/light.scss";
|
||||
}
|
||||
|
||||
[data-scheme="dark"] {
|
||||
--pre-text-color: #f8f8f2;
|
||||
--pre-background-color: #272822;
|
||||
@import "partials/highlight/dark.scss";
|
||||
}
|
||||
|
@ -57,6 +57,60 @@ class StackGallery {
|
||||
}
|
||||
|
||||
public static createGallery(container: HTMLElement) {
|
||||
/// The process of wrapping image with figure tag is done using JavaScript instead of only Hugo markdown render hook
|
||||
/// because it can not detect whether image is being wrapped by a link or not
|
||||
/// and it lead to a invalid HTML construction (<a><figure><img></figure></a>)
|
||||
|
||||
const images = container.querySelectorAll('img');
|
||||
for (const img of Array.from(images)) {
|
||||
/// Images are wrapped with figure tag if the paragraph has only images without texts
|
||||
/// This is done to allow inline images within paragraphs
|
||||
const paragraph = img.closest('p');
|
||||
|
||||
if (!paragraph || !container.contains(paragraph)) continue;
|
||||
|
||||
if (paragraph.textContent.trim() == '') {
|
||||
/// Once we insert figcaption, this check no longer works
|
||||
/// So we add a class to paragraph to mark it
|
||||
paragraph.classList.add('no-text');
|
||||
}
|
||||
|
||||
let isNewLineImage = paragraph.classList.contains('no-text');
|
||||
if (!isNewLineImage) continue;
|
||||
|
||||
const hasLink = img.parentElement.tagName == 'A';
|
||||
|
||||
let el: HTMLElement = img;
|
||||
/// Wrap image with figure tag, with flex-grow and flex-basis values extracted from img's data attributes
|
||||
const figure = document.createElement('figure');
|
||||
figure.style.setProperty('flex-grow', img.getAttribute('data-flex-grow') || '1');
|
||||
figure.style.setProperty('flex-basis', img.getAttribute('data-flex-basis') || '0');
|
||||
if (hasLink) {
|
||||
/// Wrap <a> if it exists
|
||||
el = img.parentElement;
|
||||
}
|
||||
el.parentElement.insertBefore(figure, el);
|
||||
figure.appendChild(el);
|
||||
|
||||
/// Add figcaption if it exists
|
||||
if (img.hasAttribute('alt')) {
|
||||
const figcaption = document.createElement('figcaption');
|
||||
figcaption.innerText = img.getAttribute('alt');
|
||||
figure.appendChild(figcaption);
|
||||
}
|
||||
|
||||
/// Wrap img tag with <a> tag if image was not wrapped by <a> tag
|
||||
if (!hasLink) {
|
||||
figure.className = 'gallery-image';
|
||||
|
||||
const a = document.createElement('a');
|
||||
a.href = img.src;
|
||||
a.setAttribute('target', '_blank');
|
||||
img.parentNode.insertBefore(a, img);
|
||||
a.appendChild(img);
|
||||
}
|
||||
}
|
||||
|
||||
const figuresEl = container.querySelectorAll('figure.gallery-image');
|
||||
|
||||
let currentGallery = [];
|
||||
|
@ -62,20 +62,21 @@ let Stack = {
|
||||
/**
|
||||
* Add copy button to code block
|
||||
*/
|
||||
const codeBlocks = document.querySelectorAll('.article-content > div.highlight');
|
||||
const highlights = document.querySelectorAll('.article-content div.highlight');
|
||||
const copyText = `Copy`,
|
||||
copiedText = `Copied!`;
|
||||
codeBlocks.forEach(codeBlock => {
|
||||
|
||||
highlights.forEach(highlight => {
|
||||
const copyButton = document.createElement('button');
|
||||
copyButton.innerHTML = copyText;
|
||||
copyButton.classList.add('copyCodeButton');
|
||||
codeBlock.appendChild(copyButton);
|
||||
highlight.appendChild(copyButton);
|
||||
|
||||
const pre = codeBlock.getElementsByTagName('pre');
|
||||
const code = pre[0].textContent;
|
||||
const codeBlock = highlight.querySelector('code[data-lang]');
|
||||
if (!codeBlock) return;
|
||||
|
||||
copyButton.addEventListener('click', () => {
|
||||
navigator.clipboard.writeText(code)
|
||||
navigator.clipboard.writeText(codeBlock.textContent)
|
||||
.then(() => {
|
||||
copyButton.textContent = copiedText;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
plugins:
|
||||
- name: gtag
|
||||
enabled: true
|
||||
functional: false
|
||||
optional: true
|
||||
title: Google Analytics
|
||||
description: This code gives us insight into the number of people that visit our website, where they are from and what they are clicking on. We follow the guidelines of the Italian Government.
|
||||
html_src: gdpr/gtag.html
|
||||
|
@ -4,6 +4,8 @@ theme: hugo-theme-stack
|
||||
paginate: 5
|
||||
title: Example Site
|
||||
|
||||
|
||||
|
||||
# Change it to your Disqus shortname before using
|
||||
disqusShortname: hugo-theme-stack
|
||||
|
||||
@ -29,9 +31,10 @@ params:
|
||||
rssFullContent: true
|
||||
favicon:
|
||||
|
||||
GDPRbanner:
|
||||
enabled: true
|
||||
onlyfunctional: false
|
||||
# mode: nocookie, functional, consent
|
||||
GDPR:
|
||||
enable: true
|
||||
mode: consent
|
||||
|
||||
footer:
|
||||
since: 2020
|
||||
|
@ -162,3 +162,7 @@ X<sup>n</sup> + Y<sup>n</sup> = Z<sup>n</sup>
|
||||
Press <kbd><kbd>CTRL</kbd>+<kbd>ALT</kbd>+<kbd>Delete</kbd></kbd> to end the session.
|
||||
|
||||
Most <mark>salamanders</mark> are nocturnal, and hunt for insects, worms, and other small creatures.
|
||||
|
||||
## Hyperlinked image
|
||||
|
||||
[](https://google.com)
|
||||
|
@ -36,3 +36,7 @@ Hugo ships with several [Built-in Shortcodes](https://gohugo.io/content-manageme
|
||||
## bilibilibi Shortcode
|
||||
|
||||
{{< bilibili av498363026 >}}
|
||||
|
||||
## Gist Shortcode
|
||||
|
||||
{{< gist spf13 7896402 >}}
|
||||
|
2
go.mod
2
go.mod
@ -1,3 +1,3 @@
|
||||
module github.com/CaiJimmy/hugo-theme-stack
|
||||
module github.com/CaiJimmy/hugo-theme-stack/v3
|
||||
|
||||
go 1.12
|
||||
|
@ -63,8 +63,8 @@ search:
|
||||
other: "#PAGES_COUNT pages (#TIME_SECONDS seconds)"
|
||||
|
||||
footer:
|
||||
GDPRsettings:
|
||||
modify: Manage GDPR settings
|
||||
GDPR:
|
||||
consent: Manage GDPR settings
|
||||
functional: This website use only functional cookies
|
||||
nocookie: This website doesn't use any cookie and doesn't collect any personal data
|
||||
|
||||
|
@ -62,8 +62,8 @@ search:
|
||||
other: "#PAGES_COUNT pagine (#TIME_SECONDS secondi)"
|
||||
|
||||
footer:
|
||||
GDPRsettings:
|
||||
other: Gestisci il consenso GDPR
|
||||
GDPR:
|
||||
consent: Gestisci il consenso GDPR
|
||||
functional: Questo sito web utilizza solo cookie funzionali
|
||||
nocookie: Questo sito web non usa cookie e non raccoglie dati personali
|
||||
|
||||
|
@ -25,22 +25,17 @@
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
<figure
|
||||
{{ if $galleryImage }}
|
||||
class="gallery-image"
|
||||
style="
|
||||
flex-grow: {{ div (mul $image.Width 100) $image.Height }};
|
||||
flex-basis: {{ div (mul $image.Width 240) $image.Height }}px"
|
||||
{{ end }}>
|
||||
<a href="{{ $Permalink }}" {{ if $galleryImage }}data-size="{{ $image.Width }}x{{ $image.Height }}"{{ end }}>
|
||||
<img src="{{ $Permalink }}"
|
||||
{{ with $Width }}width="{{ . }}"{{ end }}
|
||||
{{ with $Height }}height="{{ . }}"{{ end }}
|
||||
{{ with $Srcset }}srcset="{{ . }}"{{ end }}
|
||||
loading="lazy"
|
||||
{{ with $alt }}alt="{{ . }}"{{ end }}>
|
||||
</a>
|
||||
{{ with $alt }}
|
||||
<figcaption>{{ . | markdownify }}</figcaption>
|
||||
alt="{{ . }}"
|
||||
{{ end }}
|
||||
</figure>
|
||||
{{ if $galleryImage }}
|
||||
class="gallery-image"
|
||||
data-flex-grow="{{ div (mul $image.Width 100) $image.Height }}"
|
||||
data-flex-basis="{{ div (mul $image.Width 240) $image.Height }}px"
|
||||
{{ end }}
|
||||
>
|
||||
|
@ -1,3 +1,3 @@
|
||||
{{ if and .Site.Params.GDPRbanner.enabled (not .Site.Params.GDPRbanner.onlyfunctional) }}
|
||||
{{ if and .Site.Params.GDPR.enable (not (eq .Site.Params.GDPR.mode "nocookie")) }}
|
||||
{{ partial "gdpr/banner.html" . }}
|
||||
{{ end }}
|
||||
|
@ -1,6 +1,5 @@
|
||||
{{- $ThemeVersion := "3.7.0" -}}
|
||||
{{- $ThemeVersion := "3.8.0" -}}
|
||||
<footer class="site-footer">
|
||||
|
||||
<section class="copyright">
|
||||
©
|
||||
{{ if and (.Site.Params.footer.since) (ne .Site.Params.footer.since (int (now.Format "2006"))) }}
|
||||
@ -9,17 +8,19 @@
|
||||
{{ now.Format "2006" }} {{ .Site.Title }}
|
||||
</section>
|
||||
|
||||
{{ if .Site.Params.GDPR.enable }}
|
||||
<section class="GDPRbanner">
|
||||
{{ if .Site.Params.GDPRbanner.enabled }}
|
||||
{{ if not .Site.Params.GDPRbanner.onlyfunctional }}
|
||||
<a class="manage-consent" href="#manage-consent">{{ T "footer.GDPRsettings.modify" }}</a>
|
||||
{{ if (eq .Site.Params.GDPR.mode "consent") }}
|
||||
<a class="manage-consent" href="#manage-consent">{{ T "footer.GDPR.consent" }}</a>
|
||||
{{ else }}
|
||||
{{ T "footer.GDPRsettings.functional" }}
|
||||
{{ if (eq .Site.Params.GDPR.mode "functional") }}
|
||||
{{ T "footer.GDPR.functional" }}
|
||||
{{ else }}
|
||||
{{ T "footer.GDPR.nocookie" }}
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
{{ T "footer.GDPRsettings.nocookie" }}
|
||||
{{ end }}
|
||||
</section>
|
||||
{{ end }}
|
||||
|
||||
<section class="powerby">
|
||||
{{ with .Site.Params.footer.customText }}
|
||||
|
@ -1,3 +1,22 @@
|
||||
<!-- if all enabled plugins are not optional instead use mode = functionl in config file-->
|
||||
{{ range $index, $plugin := .Site.Data.gdpr.plugins }}
|
||||
{{ if and $plugin.enabled (not $plugin.optional) }}
|
||||
{{- errorf "All enabled plugins are not optional, use mode = functional in config file" -}}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
<!-- import and execute scripts because all are functional -->
|
||||
{{ if eq .Site.Params.GDPR.mode "functional" }}
|
||||
{{ range $index, $plugin := .Site.Data.gdpr.plugins }}
|
||||
{{ if $plugin.enabled }}
|
||||
{{ partial $plugin.html_src }}
|
||||
<script type="text/javascript" src="/js/{{ $plugin.js_src }}"></script>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
<!-- import and execute scripts based on user consent -->
|
||||
{{ if eq .Site.Params.GDPR.mode "consent" }}
|
||||
<!-- GDPR banner visual style -->
|
||||
<style>
|
||||
#consent-notice {padding: 1rem 1rem; display: none; text-align: center; position: fixed; bottom: 0; width: calc(100% - 2rem); background: #222; color: rgba(255,255,255,0.8);}
|
||||
@ -28,29 +47,21 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- import scripts: full if functional, partially if depends on user consent -->
|
||||
{{ range $index, $plugin := .Site.Data.gdpr.plugins }}
|
||||
{{ if $plugin.enabled }}
|
||||
{{ "<!-- " }} {{ $plugin.name }} {{ "start -->" }}
|
||||
{{ partial $plugin.html_src }}
|
||||
{{ if $plugin.functional }}
|
||||
<script type="text/javascript" src="/js/{{ $plugin.js_src }}"></script>
|
||||
{{ end }}
|
||||
{{ "<!-- " }} {{ $plugin.name }} {{ "end -->" }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
<!-- preferences dialog -->
|
||||
<div id="consent-notice"><span>We would like to use <a class="manage-consent" href="#manage-consent">third party code</a> to improve the functionality of this website.</span><button class="btn manage-consent">Manage preferences</button><button class="btn deny-consent">Deny</button><button class="btn approve-consent">Allow</button></div>
|
||||
<div id="consent-notice">
|
||||
<span>We would like to use <a class="manage-consent" href="#manage-consent">third party code</a> to improve the functionality of this website.</span>
|
||||
<button class="btn manage-consent">Manage preferences</button>
|
||||
<button class="btn deny-consent">Deny</button>
|
||||
<button class="btn approve-consent">Allow</button>
|
||||
</div>
|
||||
<div id="consent-overlay">
|
||||
<div>
|
||||
|
||||
{{ range $index, $plugin := .Site.Data.gdpr.plugins }}
|
||||
{{ if $plugin.enabled }}
|
||||
<div>
|
||||
<input type="checkbox" id="item{{ $index }}" value="1" name="item{{ $index }}" {{ if $plugin.functional }}checked disabled{{ end }} />
|
||||
<input type="checkbox" id="item{{ $index }}" value="1" name="item{{ $index }}" {{ if not $plugin.optional }}checked disabled{{ end }} />
|
||||
<label for="item{{ $index }}">
|
||||
<h3>{{ $plugin.title }}{{ if $plugin.functional}} (functional){{ end }}</h3>
|
||||
<h3>{{ $plugin.title }}{{ if not $plugin.optional}} (functional){{ end }}</h3>
|
||||
<p>{{ $plugin.description }}</p>
|
||||
</label>
|
||||
</div>
|
||||
@ -63,11 +74,21 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- execute user consent scripts -->
|
||||
<!-- import scripts library with no really action -->
|
||||
{{ range $index, $plugin := .Site.Data.gdpr.plugins }}
|
||||
{{ if $plugin.enabled }}
|
||||
{{ partial $plugin.html_src }}
|
||||
{{ if not $plugin.optional }}
|
||||
<script type="text/javascript" src="/js/{{ $plugin.js_src }}"></script>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
<!-- really execute scripts based on user consent -->
|
||||
<script>
|
||||
const scripts = [];
|
||||
{{ range $index, $plugin := .Site.Data.gdpr.plugins }}
|
||||
{{ if and $plugin.enabled (not $plugin.functional) }}
|
||||
{{ if and $plugin.enabled ($plugin.optional) }}
|
||||
scripts[{{ $index }}] = "/js/{{ $plugin.js_src }}";
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
@ -184,3 +205,4 @@
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{{ end }}
|
||||
|
@ -21,7 +21,7 @@
|
||||
<link rel="shortcut icon" href="{{ . }}" />
|
||||
{{ end }}
|
||||
|
||||
{{ if not .Site.Params.GDPRbanner.enabled }}
|
||||
{{ if not .Site.Params.GDPR.enable }}
|
||||
{{- template "_internal/google_analytics.html" . -}}
|
||||
{{ end }}
|
||||
{{- partial "head/custom.html" . -}}
|
||||
|
Loading…
Reference in New Issue
Block a user