From e93836792975403f5e00c1163720119cd1fd9832 Mon Sep 17 00:00:00 2001 From: Veillax <126523099+Veillax@users.noreply.github.com> Date: Sun, 1 Nov 2026 01:10:54 -0700 Subject: [PATCH] Fix the / and [[ menus in live preview The page's hidden text box also heard the live view's edits and showed its own menu in the wrong place, and the live line's menu was dropped when the view redrew. Only the box in use suggests now, the menu re-attaches when shown, and the caret lands inside a new code block. Co-Authored-By: Claude Sonnet 5.5 --- internal/web/static/editor.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/internal/web/static/editor.js b/internal/web/static/editor.js index a93b372..d097dce 100644 --- a/internal/web/static/editor.js +++ b/internal/web/static/editor.js @@ -53,6 +53,7 @@ function makePopup(ta, wrap) { get open() { return !el.hidden; }, show(list, pick, pos) { if (!list.length) return pop.hide(); + if (el.parentNode !== wrap) wrap.append(el); // a redraw of the live view can drop it items = list; onPick = pick; sel = 0; draw(); el.hidden = false; const c = caretXY(ta, pos); el.style.left = Math.max(0, Math.min(ta.offsetLeft + c.x, wrap.clientWidth - 270)) + 'px'; @@ -79,7 +80,8 @@ function enhance(ta, wrap) { const pop = makePopup(ta, wrap); function check() { - if (ta.selectionStart !== ta.selectionEnd) return pop.hide(); + // the page's own text box also hears the live view's edits (it holds the text); only the box in use may suggest + if (document.activeElement !== ta || ta.selectionStart !== ta.selectionEnd) return pop.hide(); const pos = ta.selectionStart, ls = lineStart(ta.value, pos), before = ta.value.slice(ls, pos); let m; if ((m = /\[\[([^\[\]|\n]*)$/.exec(before))) { @@ -93,7 +95,9 @@ function enhance(ta, wrap) { pop.show(SLASH.filter(c => !q || c.name.toLowerCase().includes(q) || c.keys.includes(q)), c => { const text = typeof c.text === 'function' ? c.text() : c.text; replaceRange(ta, from, pos, text); - if (c.caret) ta.setSelectionRange(from + c.caret, from + c.caret); + // in the live view a command that adds lines redraws it, and the box being typed in is a new one + const cur = ta.isConnected ? ta : wrap.querySelector('textarea.live-edit') || ta; + if (c.caret) cur.setSelectionRange(from + c.caret, from + c.caret); if (c.again) check(); }, pos); } else pop.hide();