function setCopyStatus(message, isError) { const status = document.getElementById("copy-status"); if (!status) return; status.textContent = message; status.className = isError ? "copy-status error" : "copy-status success"; } function getNewsletterHtml() { const htmlSource = document.getElementById("newsletter-html-source"); const htmlDisplay = document.getElementById("newsletter-html-display"); const value = htmlSource?.value.trim() || htmlDisplay?.value.trim() || ""; return value; } function getNewsletterOutlookHtml() { const outlookSource = document.getElementById("newsletter-outlook-source"); const outlook = outlookSource ? outlookSource.value.trim() : ""; if (outlook) return outlook; return getNewsletterHtml(); } function getNewsletterPlain() { const plainSource = document.getElementById("newsletter-plain-source"); return plainSource ? plainSource.value : ""; } function wrapCfHtml(html) { const fragmentStart = ""; const fragmentEnd = ""; const bodyMatch = html.match(/]*>([\s\S]*)<\/body>/i); const inner = bodyMatch ? bodyMatch[1].trim() : html; const documentHtml = `${fragmentStart}${inner}${fragmentEnd}`; const pad = (value) => String(value).padStart(10, "0"); const headerPlaceholder = "StartHTML:0000000000\r\nEndHTML:0000000000\r\nStartFragment:0000000000\r\nEndFragment:0000000000\r\n"; const prefix = `Version:0.9\r\n${headerPlaceholder}`; const startHtml = prefix.length; const endHtml = startHtml + documentHtml.length; const startFragment = startHtml + documentHtml.indexOf(fragmentStart) + fragmentStart.length; const endFragment = startHtml + documentHtml.indexOf(fragmentEnd); return ( `Version:0.9\r\n` + `StartHTML:${pad(startHtml)}\r\n` + `EndHTML:${pad(endHtml)}\r\n` + `StartFragment:${pad(startFragment)}\r\n` + `EndFragment:${pad(endFragment)}\r\n` + documentHtml ); } function copyFromTextarea(textarea) { if (!textarea || !textarea.value) return false; const previousActive = document.activeElement; textarea.removeAttribute("readonly"); textarea.focus({ preventScroll: true }); textarea.select(); textarea.setSelectionRange(0, textarea.value.length); let ok = false; try { ok = document.execCommand("copy"); } catch (err) { console.warn("execCommand copy from textarea failed.", err); ok = false; } finally { textarea.setAttribute("readonly", ""); if (previousActive && typeof previousActive.focus === "function") { previousActive.focus({ preventScroll: true }); } } return ok; } function copyTextWithFallback(text) { if (!text) return false; const pageTextareas = [ document.getElementById("newsletter-html-display"), document.getElementById("newsletter-html-source"), document.getElementById("newsletter-outlook-source"), document.getElementById("newsletter-plain-source"), ]; for (const textarea of pageTextareas) { if (textarea && textarea.value === text && copyFromTextarea(textarea)) { return true; } } const textarea = document.createElement("textarea"); textarea.value = text; textarea.setAttribute("aria-hidden", "true"); textarea.style.position = "fixed"; textarea.style.top = "0"; textarea.style.left = "0"; textarea.style.width = "2px"; textarea.style.height = "2px"; textarea.style.padding = "0"; textarea.style.border = "none"; textarea.style.outline = "none"; textarea.style.boxShadow = "none"; textarea.style.background = "transparent"; document.body.appendChild(textarea); let ok = false; try { textarea.focus({ preventScroll: true }); textarea.select(); textarea.setSelectionRange(0, text.length); ok = document.execCommand("copy"); } catch (err) { console.warn("execCommand copy from temporary textarea failed.", err); ok = false; } finally { document.body.removeChild(textarea); } return ok; } function copyHtmlWithFallback(html) { const container = document.createElement("div"); container.innerHTML = html; container.contentEditable = "true"; container.setAttribute("aria-hidden", "true"); container.style.position = "fixed"; container.style.left = "0"; container.style.top = "0"; container.style.width = "600px"; container.style.height = "1px"; container.style.overflow = "hidden"; container.style.opacity = "0"; container.style.pointerEvents = "none"; container.style.background = "#FFFFFF"; document.body.appendChild(container); const range = document.createRange(); range.selectNodeContents(container); const selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(range); let ok = false; try { ok = document.execCommand("copy"); } catch (err) { console.warn("execCommand HTML copy failed.", err); ok = false; } finally { selection.removeAllRanges(); document.body.removeChild(container); } if (!ok) { ok = copyTextWithFallback(wrapCfHtml(html)); } return ok; } async function copyText(text) { if (!text) return false; if (copyTextWithFallback(text)) { return true; } if (navigator.clipboard && window.isSecureContext) { try { await navigator.clipboard.writeText(text); return true; } catch (err) { console.warn("Clipboard API text copy failed.", err); } } return false; } async function copyForOutlook() { const html = getNewsletterOutlookHtml(); const plain = getNewsletterPlain(); if (!html) { setCopyStatus("Bitte zuerst einen Newsletter generieren.", true); return; } if (copyHtmlWithFallback(html)) { setCopyStatus("Newsletter für Outlook kopiert. Mit Strg+V einfügen (ggf. „Format beibehalten“)."); return; } const cfHtml = wrapCfHtml(html); if (navigator.clipboard && window.ClipboardItem && window.isSecureContext) { try { await navigator.clipboard.write([ new ClipboardItem({ "text/html": new Blob([cfHtml], { type: "text/html" }), "text/plain": new Blob([plain], { type: "text/plain" }), }), ]); setCopyStatus("Newsletter für Outlook kopiert. Mit Strg+V einfügen (ggf. „Format beibehalten“)."); return; } catch (err) { console.warn("Clipboard API HTML copy failed.", err); } } setCopyStatus("Kopieren fehlgeschlagen. Bitte „HTML herunterladen“ verwenden.", true); } async function copyHtmlSource() { const html = getNewsletterHtml(); if (!html) { setCopyStatus("Bitte zuerst einen Newsletter generieren.", true); return; } const displayArea = document.getElementById("newsletter-html-display"); const sourceArea = document.getElementById("newsletter-html-source"); const textarea = displayArea?.value ? displayArea : sourceArea; if (textarea && copyFromTextarea(textarea)) { setCopyStatus("HTML-Quelltext kopiert."); return; } if (copyTextWithFallback(html)) { setCopyStatus("HTML-Quelltext kopiert."); return; } if (navigator.clipboard && window.isSecureContext) { try { await navigator.clipboard.writeText(html); setCopyStatus("HTML-Quelltext kopiert."); return; } catch (err) { console.warn("Clipboard API HTML source copy failed.", err); } } if (textarea) { textarea.focus({ preventScroll: true }); textarea.select(); } setCopyStatus( "Automatisches Kopieren nicht möglich. HTML-Feld unten ist markiert – bitte Strg+C drücken.", true ); } function downloadHtml() { const html = getNewsletterOutlookHtml(); if (!html) { setCopyStatus("Bitte zuerst einen Newsletter generieren.", true); return; } const stamp = new Date().toISOString().slice(0, 10); const filename = `wiki-newsletter-${stamp}.html`; const blob = new Blob([html], { type: "text/html;charset=utf-8" }); const url = URL.createObjectURL(blob); const link = document.createElement("a"); link.href = url; link.download = filename; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(url); setCopyStatus(`HTML gespeichert als ${filename}. Datei in Outlook öffnen oder Inhalt kopieren.`); } document.addEventListener("DOMContentLoaded", () => { const outlookSource = document.getElementById("newsletter-outlook-source"); const htmlSource = document.getElementById("newsletter-html-source"); const frame = document.getElementById("newsletter-preview-frame"); const previewHtml = outlookSource?.value.trim() || htmlSource?.value.trim() || ""; if (frame && previewHtml) { frame.srcdoc = previewHtml; } document.getElementById("copy-outlook-btn")?.addEventListener("click", copyForOutlook); document.getElementById("copy-html-source-btn")?.addEventListener("click", copyHtmlSource); document.getElementById("download-html-btn")?.addEventListener("click", downloadHtml); });