Vorlage beim Durchswitchen ersetzen statt stapeln (v2.6.0)

HTML-Vorlagen werden jetzt in <div id="hps-vorlage"> gewickelt und
direkt im Editor-DOM eingefügt. Vor dem Einfügen wird ein evtl. schon
vorhandener hps-vorlage-Block entfernt — so ersetzt Durchswitchen die
Vorlage statt sie oben draufzustapeln. insertText bleibt als Fallback.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019XcAzPQhKgwS4HNzvXEFeN
This commit is contained in:
Kendrick Bollens
2026-07-22 18:34:26 +02:00
parent 169fc68f18
commit 2b6e2267c2
3 changed files with 34 additions and 15 deletions

View File

@@ -276,30 +276,49 @@ async function handleInsertTemplate(msg) {
const newBody = msg.text + (old ? '\n' + old : ''); const newBody = msg.text + (old ? '\n' + old : '');
await browser.compose.setComposeDetails(tab.id, { plainTextBody: newBody }); await browser.compose.setComposeDetails(tab.id, { plainTextBody: newBody });
} else { } else {
// HTML mode: use insertText API to go through the editor's rendering pipeline // HTML mode: wrap the template in a marker element (id=hps-vorlage) and
// replace any previously inserted one — so durchswitchen ersetzt statt stapelt.
const htmlContent = isHtmlTemplate ? msg.text : msg.text.replace(/\n/g, '<br>'); const htmlContent = isHtmlTemplate ? msg.text : msg.text.replace(/\n/g, '<br>');
// Move cursor to beginning of body first via script injection // Directly manipulate the editor DOM: remove the old template block (if any),
await browser.tabs.executeScript(tab.id, { // then insert the new one at the top of the body. Returns true on success.
const injected = await browser.tabs.executeScript(tab.id, {
code: ` code: `
const editor = document.getElementById('messageEditor'); (function () {
const editorDoc = editor ? editor.contentDocument : document; const editor = document.getElementById('messageEditor');
const body = editorDoc.body; const editorDoc = editor ? editor.contentDocument : document;
if (body) { const body = editorDoc && editorDoc.body;
if (!body) return false;
// Remove a previously inserted template block, so switching replaces it
const prev = editorDoc.getElementById('hps-vorlage');
if (prev) prev.remove();
// Wrap the new template in a marker element with a stable id
const wrapper = editorDoc.createElement('div');
wrapper.id = 'hps-vorlage';
wrapper.innerHTML = ${JSON.stringify(htmlContent)};
// Insert at the very top of the body (above quote/signature/typed text)
body.insertBefore(wrapper, body.firstChild);
// Place the cursor right after the inserted block
const range = editorDoc.createRange(); const range = editorDoc.createRange();
range.setStart(body, 0); range.setStartAfter(wrapper);
range.collapse(true); range.collapse(true);
const sel = editorDoc.getSelection(); const sel = editorDoc.getSelection();
sel.removeAllRanges(); sel.removeAllRanges();
sel.addRange(range); sel.addRange(range);
} return true;
})();
` `
}).catch(() => { }).then(r => (Array.isArray(r) ? r[0] : r)).catch(() => false);
// Fallback: some TB versions structure the editor differently
});
// Insert HTML at cursor position - this goes through the editor's render pipeline if (!injected) {
await browser.compose.insertText(tab.id, htmlContent + '<br>', { insertAsText: false }); // Fallback: editor DOM not reachable (TB version differences) — use the
// insertText pipeline. Note: this variant cannot replace, only prepend.
await browser.compose.insertText(tab.id, htmlContent + '<br>', { insertAsText: false });
}
} }
} catch (e) { } catch (e) {

View File

@@ -1,7 +1,7 @@
{ {
"manifest_version": 2, "manifest_version": 2,
"name": "HPS Vorlagen & Signaturen", "name": "HPS Vorlagen & Signaturen",
"version": "2.5.0", "version": "2.6.0",
"description": "Vorlagen- und Signaturverwaltung für Hotel Park Soltau mit Git-Sync", "description": "Vorlagen- und Signaturverwaltung für Hotel Park Soltau mit Git-Sync",
"browser_specific_settings": { "browser_specific_settings": {
"gecko": { "gecko": {

Binary file not shown.