zunanje povezave se odpirajo v novem zavihku (delegiran klik pokrije tudi povezave v HTML clankov)

This commit is contained in:
folx bot
2026-08-25 11:53:28 +02:00
parent 0b60da3593
commit 2d321b4e57
3 changed files with 29 additions and 1 deletions
+26
View File
@@ -25,6 +25,31 @@ import AdminPushPage from "@/pages/admin-push";
import CookieConsent from "@/components/cookie-consent"; import CookieConsent from "@/components/cookie-consent";
import MobileStickyAd from "@/components/mobile-sticky-ad"; import MobileStickyAd from "@/components/mobile-sticky-ad";
// Vse povezave, ki vodijo z nase domene, se odprejo v novem zavihku. Delegiran
// klik pokrije tudi povezave znotraj HTML vsebine clankov, kjer atributa
// target ne moremo nastaviti vnaprej.
function ExternalLinksNewTab() {
useEffect(() => {
const onClick = (e: MouseEvent) => {
if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
const el = e.target as HTMLElement | null;
const a = el && el.closest ? (el.closest("a[href]") as HTMLAnchorElement | null) : null;
if (!a) return;
const href = a.getAttribute("href") || "";
if (!/^https?:\/\//i.test(href)) return;
let u: URL;
try { u = new URL(href, window.location.href); } catch { return; }
if (u.host === window.location.host) return;
if (a.target === "_blank") return;
e.preventDefault();
window.open(u.href, "_blank", "noopener,noreferrer");
};
document.addEventListener("click", onClick);
return () => document.removeEventListener("click", onClick);
}, []);
return null;
}
function ScrollToTop() { function ScrollToTop() {
const [location] = useLocation(); const [location] = useLocation();
useEffect(() => { useEffect(() => {
@@ -37,6 +62,7 @@ function Router() {
return ( return (
<div> <div>
<ScrollToTop /> <ScrollToTop />
<ExternalLinksNewTab />
<Switch> <Switch>
<Route path="/" component={Home} /> <Route path="/" component={Home} />
<Route path="/search" component={SearchPage} /> <Route path="/search" component={SearchPage} />
+2
View File
@@ -138,6 +138,8 @@ export default function EmpfangPage() {
Besuchen Sie{" "} Besuchen Sie{" "}
<a <a
href="https://www.folx.tv" href="https://www.folx.tv"
target="_blank"
rel="noopener"
className="text-primary hover:underline font-medium" className="text-primary hover:underline font-medium"
data-testid="link-livestream" data-testid="link-livestream"
> >
+1 -1
View File
@@ -193,7 +193,7 @@ export function serveStatic(app: Express) {
`<iframe width="640" height="360" src="${escapeHtml(embedUrl)}" title="${escapeHtml(v.shortTitle)}" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen style="border:0;max-width:100%;"></iframe>`, `<iframe width="640" height="360" src="${escapeHtml(embedUrl)}" title="${escapeHtml(v.shortTitle)}" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen style="border:0;max-width:100%;"></iframe>`,
`<p><strong>${escapeHtml(desc)}</strong></p>`, `<p><strong>${escapeHtml(desc)}</strong></p>`,
chapterHtml, chapterHtml,
`<p><a href="${escapeHtml(v.youtubeUrl)}" rel="noopener">Das ganze Video auf YouTube ansehen</a></p>`, `<p><a href="${escapeHtml(v.youtubeUrl)}" target="_blank" rel="noopener">Das ganze Video auf YouTube ansehen</a></p>`,
v.articleUrl ? `<p><a href="${escapeHtml(v.articleUrl)}">Ganzer Artikel auf folx.tv</a></p>` : "", v.articleUrl ? `<p><a href="${escapeHtml(v.articleUrl)}">Ganzer Artikel auf folx.tv</a></p>` : "",
descHtml ? `<h2>Zum Video</h2>${descHtml}` : "", descHtml ? `<h2>Zum Video</h2>${descHtml}` : "",
"</article>", "</article>",