diff --git a/web-editor/public/app.js b/web-editor/public/app.js index 1459522..0c303c3 100644 --- a/web-editor/public/app.js +++ b/web-editor/public/app.js @@ -374,6 +374,38 @@ ed = editor; editor.on('init', function () { edReady = true; }); editor.on('input ExecCommand Undo Redo SetContent paste', function () { if (!suppressDirty) markDirty(); }); + // Robustes Einfügen aus externen Quellen (z.B. E-Mails). TinyMCEs eigener + // Fallback (verstecktes „Pastebin"-Feld) schlägt bei manchen Quellen still + // fehl → „nichts passiert". Wir lesen die Zwischenablage direkt aus und + // fügen HTML mitsamt Formatierung ein. Interner Copy/Paste (funktioniert + // bereits) und Bild-Paste bleiben dem Standard-Handler überlassen. + editor.on('paste', function (e) { + const cd = e.clipboardData; + if (!cd) return; // keine Zwischenablage → Standard-Handler versuchen lassen + let html = ''; + try { html = cd.getData('text/html') || ''; } catch (_) {} + // TinyMCE-interner Inhalt trägt diesen Marker → Standard-Pfad übernehmen. + if (html.indexOf('x-tinymce/html') !== -1) return; + let text = ''; + try { text = cd.getData('text/plain') || ''; } catch (_) {} + // Reines Bild (Screenshot o.ä.) → TinyMCEs Bildverarbeitung übernehmen. + const hasImage = + (cd.types && Array.prototype.indexOf.call(cd.types, 'Files') !== -1) || + (cd.items && Array.prototype.some.call(cd.items, function (it) { return it.kind === 'file' && /^image\//.test(it.type); })); + if (!html && !text && hasImage) return; + if (!html && !text) return; // nichts Brauchbares → Standard-Fallback lassen + e.preventDefault(); // unterdrückt den fragilen TinyMCE-Standard-Handler + let content; + if (html) { + // Office/Outlook markieren die eigentliche Auswahl per Fragment-Kommentar. + const frag = /([\s\S]*?)/i.exec(html); + content = frag ? frag[1] : html; + } else { + content = editor.dom.encode(text).replace(/\r\n?|\n/g, '
'); + } + editor.insertContent(content); + markDirty(); + }); }, }).then(() => { edReady = true; }); }