feat: Externe Quellen mit klickbaren Links (neuer Tab) + Kiosk-Modus
- Label "Externe Quelle (Links)" -> "Externe Quellen" (de/en) - Quelle-URLs werden via linkify-Partial anklickbar, oeffnen in neuem Tab - Neuer Kiosk-Modus: ?kiosk=true macht externe Links unklickbar (bleibt fuer die Session aktiv, verlassen mit ?kiosk=false)
This commit is contained in:
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Kiosk-Modus für Ausstellungs-/Terminal-Betrieb.
|
||||||
|
*
|
||||||
|
* Aktivieren: beliebige URL mit ?kiosk=true (oder ?kiosk=1) aufrufen.
|
||||||
|
* Deaktivieren: ?kiosk=false (oder ?kiosk=0).
|
||||||
|
*
|
||||||
|
* Ist der Modus aktiv, bleibt er für die gesamte Browser-Session erhalten
|
||||||
|
* (auch beim Weiterklicken im Menü, ohne den Parameter erneut anzuhängen).
|
||||||
|
* Externe Links (anderer Host) sowie mailto:/tel: werden dann unklickbar
|
||||||
|
* gemacht – der Linktext bleibt lesbar. Interne Navigation bleibt möglich,
|
||||||
|
* damit Karte und Schauplätze weiter erkundet werden können.
|
||||||
|
*/
|
||||||
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var KEY = "op-kiosk";
|
||||||
|
var params = new URLSearchParams(window.location.search);
|
||||||
|
|
||||||
|
// Parameter setzt/löscht den Session-Zustand
|
||||||
|
if (params.has("kiosk")) {
|
||||||
|
var v = params.get("kiosk").toLowerCase();
|
||||||
|
var on = v === "" || v === "true" || v === "1" || v === "yes";
|
||||||
|
try {
|
||||||
|
if (on) { sessionStorage.setItem(KEY, "1"); }
|
||||||
|
else { sessionStorage.removeItem(KEY); }
|
||||||
|
} catch (e) { /* Storage evtl. gesperrt – dann nur für diese Seite aktiv */ }
|
||||||
|
if (!on) { document.documentElement.classList.remove("op-kiosk"); return; }
|
||||||
|
}
|
||||||
|
|
||||||
|
var active = false;
|
||||||
|
try { active = sessionStorage.getItem(KEY) === "1"; } catch (e) { /* ignore */ }
|
||||||
|
if (!active && !params.has("kiosk")) { return; }
|
||||||
|
if (!active && params.has("kiosk")) {
|
||||||
|
// Storage gesperrt, aber Parameter aktiv → nur für diese Seite
|
||||||
|
active = params.get("kiosk").toLowerCase() !== "false";
|
||||||
|
}
|
||||||
|
if (!active) { return; }
|
||||||
|
|
||||||
|
document.documentElement.classList.add("op-kiosk");
|
||||||
|
|
||||||
|
function neutralize() {
|
||||||
|
var host = window.location.hostname;
|
||||||
|
var links = document.querySelectorAll("a[href]");
|
||||||
|
for (var i = 0; i < links.length; i++) {
|
||||||
|
var a = links[i];
|
||||||
|
var url;
|
||||||
|
try { url = new URL(a.href, window.location.href); } catch (e) { continue; }
|
||||||
|
|
||||||
|
var web = url.protocol === "http:" || url.protocol === "https:";
|
||||||
|
var block =
|
||||||
|
(web && url.hostname !== host) ||
|
||||||
|
url.protocol === "mailto:" ||
|
||||||
|
url.protocol === "tel:";
|
||||||
|
|
||||||
|
if (!block) { continue; }
|
||||||
|
|
||||||
|
a.classList.add("op-link-disabled");
|
||||||
|
a.setAttribute("aria-disabled", "true");
|
||||||
|
a.setAttribute("tabindex", "-1");
|
||||||
|
a.removeAttribute("target");
|
||||||
|
a.dataset.kioskHref = a.getAttribute("href");
|
||||||
|
a.removeAttribute("href");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.readyState === "loading") {
|
||||||
|
document.addEventListener("DOMContentLoaded", neutralize);
|
||||||
|
} else {
|
||||||
|
neutralize();
|
||||||
|
}
|
||||||
|
})();
|
||||||
+1
-1
@@ -35,7 +35,7 @@ other = "Schauplätze"
|
|||||||
other = "Alle Schauplätze"
|
other = "Alle Schauplätze"
|
||||||
|
|
||||||
[externalSource]
|
[externalSource]
|
||||||
other = "Externe Quelle (Links):"
|
other = "Externe Quellen"
|
||||||
|
|
||||||
[directions]
|
[directions]
|
||||||
other = "Anfahrt per OpenStreetMap"
|
other = "Anfahrt per OpenStreetMap"
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ other = "Locations"
|
|||||||
other = "All locations"
|
other = "All locations"
|
||||||
|
|
||||||
[externalSource]
|
[externalSource]
|
||||||
other = "External source (links):"
|
other = "External sources"
|
||||||
|
|
||||||
[directions]
|
[directions]
|
||||||
other = "Directions via OpenStreetMap"
|
other = "Directions via OpenStreetMap"
|
||||||
|
|||||||
@@ -694,6 +694,12 @@ a:hover { color: var(--op-blau-dunkel); }
|
|||||||
.op-theme-blau .op-bildnachweis { color: rgba(255,255,255,.7); }
|
.op-theme-blau .op-bildnachweis { color: rgba(255,255,255,.7); }
|
||||||
.op-theme-blau .op-bildnachweis a { color: var(--op-gelb); }
|
.op-theme-blau .op-bildnachweis a { color: var(--op-gelb); }
|
||||||
.op-content-box .op-quelle-head { font-weight: 700; color: var(--op-blau); margin-top: 1.5rem; }
|
.op-content-box .op-quelle-head { font-weight: 700; color: var(--op-blau); margin-top: 1.5rem; }
|
||||||
|
.op-content-box .op-quelle-link { color: var(--op-blau); text-decoration: underline; word-break: break-word; }
|
||||||
|
.op-theme-blau .op-content-box .op-quelle-link { color: var(--op-gelb); }
|
||||||
|
|
||||||
|
/* Kiosk-Modus (?kiosk=true): externe Links werden von kiosk.js entschärft und
|
||||||
|
sollen wie normaler Fliesstext wirken – nicht anklickbar, keine Link-Optik. */
|
||||||
|
.op-link-disabled { color: inherit; text-decoration: none; cursor: default; pointer-events: none; }
|
||||||
|
|
||||||
/* =========================================================================
|
/* =========================================================================
|
||||||
16. TOUCH-KIOSK & BARRIEREFREIHEIT
|
16. TOUCH-KIOSK & BARRIEREFREIHEIT
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{{- /*
|
||||||
|
linkify.html – wandelt nackte http(s)-URLs in einem Textblock in anklickbare
|
||||||
|
Links um (neuer Tab). Alles andere bleibt unveraendert.
|
||||||
|
Aufruf: {{ partial "linkify.html" .Params.quelle }}
|
||||||
|
Die erzeugten Links tragen die Klasse op-quelle-link; im Kiosk-Modus
|
||||||
|
(?kiosk=true) werden externe Links per kiosk.js ohnehin deaktiviert.
|
||||||
|
*/ -}}
|
||||||
|
{{- $s := . -}}
|
||||||
|
{{- $s = replaceRE `(https?://[^\s<>\]]+)` `<a class="op-quelle-link" href="${1}" target="_blank" rel="noopener noreferrer">${1}</a>` $s -}}
|
||||||
|
{{- $s | safeHTML -}}
|
||||||
@@ -1,3 +1,8 @@
|
|||||||
|
{{/* Kiosk-Modus (?kiosk=true) – global auf allen Seiten */}}
|
||||||
|
{{ $kiosk := resources.Get "js/kiosk.js" }}
|
||||||
|
{{ if hugo.IsProduction }}{{ $kiosk = $kiosk | minify | fingerprint }}{{ end }}
|
||||||
|
<script src="{{ $kiosk.RelPermalink }}"{{ with $kiosk.Data.Integrity }} integrity="{{ . }}"{{ end }}></script>
|
||||||
|
|
||||||
{{/* Karten-JS nur auf Karten-Seiten (Home + Schauplätze) laden */}}
|
{{/* Karten-JS nur auf Karten-Seiten (Home + Schauplätze) laden */}}
|
||||||
{{ if or .IsHome (eq .Type "schauplaetze") (eq .Type "kategorien") (eq .Type "erinnerungsorte") }}
|
{{ if or .IsHome (eq .Type "schauplaetze") (eq .Type "kategorien") (eq .Type "erinnerungsorte") }}
|
||||||
<script src="{{ "vendor/leaflet/leaflet.js" | relURL }}"></script>
|
<script src="{{ "vendor/leaflet/leaflet.js" | relURL }}"></script>
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
{{ .Content }}
|
{{ .Content }}
|
||||||
{{ with .Params.quelle }}
|
{{ with .Params.quelle }}
|
||||||
<p class="op-quelle-head">{{ i18n "externalSource" }}</p>
|
<p class="op-quelle-head">{{ i18n "externalSource" }}</p>
|
||||||
<p class="op-meta uk-margin-remove-top">{{ . | safeHTML }}</p>
|
<p class="op-meta uk-margin-remove-top">{{ partial "linkify.html" . }}</p>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user