'use client'; import { useEffect } from 'react'; import { useIsDesktopClient } from '@/lib/desktop-client'; /** * DesktopExternalLinks (quick-261001-cxo) — Links mit `target="_blank"` * (Favoriten, „In neuem Tab öffnen“ bei XFrame/eigenen Modulen, Quellen im * Ausschreibungs-Radar) taten im Desktop-Client beim Klick nichts, waehrend * `window.open` (Such-Widget) ueber `on_new_window` im System-Browser landet. * * Ursache (VM 8233, 01.10.2026, gemessen): tauri-plugin-opener schleust ein * Skript ein, das auf `window` solche Klicks abfaengt, `preventDefault()` * ruft und `plugin:opener|open_url` aufruft -- von der Server-Seite aus ist * dieser Aufruf nicht freigegeben, der Klick verpufft. Dieser Helfer kommt * ihm zuvor und oeffnet per `window.open`; das Opener-Skript sieht den Klick * dann als verhindert und tut nichts. * * Lauscht deshalb auf `document` in der Bubble-Phase: NACH Reacts Handlern * (Wurzel `document`, frueher registriert) -- ein Klick, den die Seite selbst * verhindert (Favoriten im Bearbeiten-Modus), bleibt verhindert --, aber VOR * dem Opener-Skript auf `window`. Nur http/https. */ function externalTarget(event: MouseEvent): HTMLAnchorElement | null { if (event.defaultPrevented) return null; // Linksklick und Mittelklick oeffnen beide ein neues Fenster. if (event.button !== 0 && event.button !== 1) return null; const target = event.target; if (!(target instanceof Element)) return null; const anchor = target.closest('a[href]'); if (!(anchor instanceof HTMLAnchorElement)) return null; if (anchor.target !== '_blank') return null; if (anchor.protocol !== 'http:' && anchor.protocol !== 'https:') return null; return anchor; } export function DesktopExternalLinks() { const isDesktop = useIsDesktopClient(); useEffect(() => { if (!isDesktop) return; const handler = (event: MouseEvent) => { if (event.type === 'auxclick' && event.button !== 1) return; if (event.type === 'click' && event.button !== 0) return; const anchor = externalTarget(event); if (!anchor) return; event.preventDefault(); window.open(anchor.href, '_blank', 'noopener,noreferrer'); }; document.addEventListener('click', handler); document.addEventListener('auxclick', handler); return () => { document.removeEventListener('click', handler); document.removeEventListener('auxclick', handler); }; }, [isDesktop]); return null; }