From f426970d4c5475d6c9288b61847d99bd05b79e43 Mon Sep 17 00:00:00 2001 From: mwiegand Date: Sun, 17 May 2026 12:43:12 +0200 Subject: [PATCH] feat(editor): re-init CM6 on htmx:afterSwap into #modal-content editor.js exposes initEditors(root) and listens for htmx:afterSwap so editor textareas that arrive via modal swap get CM6 mounted. The DOMContentLoaded path remains for first-paint mounting. Co-Authored-By: Claude Opus 4.7 (1M context) --- l4d2web/l4d2web/static/js/editor.js | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/l4d2web/l4d2web/static/js/editor.js b/l4d2web/l4d2web/static/js/editor.js index df1742f..258042d 100644 --- a/l4d2web/l4d2web/static/js/editor.js +++ b/l4d2web/l4d2web/static/js/editor.js @@ -86,18 +86,31 @@ } } - function init() { - for (const ta of document.querySelectorAll("textarea[data-editor-language]")) { + function initEditors(root) { + const scope = root || document; + for (const ta of scope.querySelectorAll("textarea[data-editor-language]")) { mountOne(ta).catch(err => { console.error("[editor] mount failed", err); - unhideTextarea(ta); // restore the form-usable raw textarea + unhideTextarea(ta); }); } } if (document.readyState === "loading") { - document.addEventListener("DOMContentLoaded", init); + document.addEventListener("DOMContentLoaded", () => initEditors(document)); } else { - init(); + initEditors(document); + } + + // Re-init editors that arrive via HTMX swap (modal content, etc.). + document.body.addEventListener("htmx:afterSwap", (event) => { + if (event.target && event.target.id === "modal-content") { + initEditors(event.target); + } + }); + + // Expose for callers that need to re-mount imperatively. + if (window.__editor) { + window.__editor.initEditors = initEditors; } })();