diff --git a/docs/superpowers/plans/2026-05-16-textarea-code-editor.md b/docs/superpowers/plans/2026-05-16-textarea-code-editor.md index 7c27be4..edc1bd9 100644 --- a/docs/superpowers/plans/2026-05-16-textarea-code-editor.md +++ b/docs/superpowers/plans/2026-05-16-textarea-code-editor.md @@ -440,12 +440,15 @@ Key design decisions baked into the final file (both the initial skeleton and th }; } - // For "auto" language: look for a filename input near the textarea - // (the files-editor modal). Returns the or null. + // For "auto" language: look for a filename input inside the nearest + // enclosing dialog or .modal. Returns the or null. + // Intentionally does NOT walk up to
: an "auto" textarea + // outside a modal scope degrades to "plain" rather than picking up + // some unrelated .files-editor-filename elsewhere in the document. function findFilenameInput(textarea) { - const modal = textarea.closest("dialog, .modal, body"); - if (!modal) return null; - return modal.querySelector(".files-editor-filename"); + const scope = textarea.closest("dialog, .modal"); + if (!scope) return null; + return scope.querySelector(".files-editor-filename"); } function mount(textarea) { @@ -491,8 +494,14 @@ Key design decisions baked into the final file (both the initial skeleton and th jar, language, setValue: function (text) { + // updateCode does not invoke the onUpdate mirror, so fire the + // same textarea sync + input event here for consistency. Any + // listener watching the textarea sees external setValue calls + // (e.g. files-overlay loading a file into the modal) the same + // way it sees user typing. instance.jar.updateCode(text); textarea.value = text; + textarea.dispatchEvent(new Event("input", { bubbles: true })); }, getValue: function () { return instance.jar.toString(); diff --git a/l4d2web/l4d2web/static/js/editor.js b/l4d2web/l4d2web/static/js/editor.js index 9b9ee63..7424fbb 100644 --- a/l4d2web/l4d2web/static/js/editor.js +++ b/l4d2web/l4d2web/static/js/editor.js @@ -37,12 +37,15 @@ }; } - // For "auto" language: look for a filename input near the textarea - // (the files-editor modal). Returns the or null. + // For "auto" language: look for a filename input inside the nearest + // enclosing dialog or .modal. Returns the or null. + // Intentionally does NOT walk up to : an "auto" textarea + // outside a modal scope degrades to "plain" rather than picking up + // some unrelated .files-editor-filename elsewhere in the document. function findFilenameInput(textarea) { - const modal = textarea.closest("dialog, .modal, body"); - if (!modal) return null; - return modal.querySelector(".files-editor-filename"); + const scope = textarea.closest("dialog, .modal"); + if (!scope) return null; + return scope.querySelector(".files-editor-filename"); } function mount(textarea) { @@ -88,8 +91,14 @@ jar, language, setValue: function (text) { + // updateCode does not invoke the onUpdate mirror, so fire the + // same textarea sync + input event here for consistency. Any + // listener watching the textarea sees external setValue calls + // (e.g. files-overlay loading a file into the modal) the same + // way it sees user typing. instance.jar.updateCode(text); textarea.value = text; + textarea.dispatchEvent(new Event("input", { bubbles: true })); }, getValue: function () { return instance.jar.toString();