fix: bubble menu always positioned at selection end
CI / lint (push) Successful in 15s
CI / security (push) Successful in 9s
CI / test (push) Successful in 24s
CI / build (push) Successful in 2s

Changed from selectionStart to selectionEnd so bubble follows where user finished selecting. Removed broken fallback that repositioned to textarea bottom on every scroll. Simple viewport clamp instead.
This commit is contained in:
2026-06-06 00:04:04 -04:00
parent 76a5b23e96
commit 53cd202a93
+5 -6
View File
@@ -782,15 +782,14 @@ body { font-family: var(--sans); background: var(--bg); color: var(--text); heig
// ---- Bubble menu ---- // ---- Bubble menu ----
function showBubble() { function showBubble() {
if (ta.selectionStart === ta.selectionEnd) { hideBubble(); return; } if (ta.selectionStart === ta.selectionEnd) { hideBubble(); return; }
// Position below the selection start, using caret pixel calc // Position below selection END (where user finished selecting)
var pt = caretToPixel(ta.selectionStart); var pt = caretToPixel(ta.selectionEnd);
// Convert from editorWrap-relative to viewport-relative
var wr = editorWrap.getBoundingClientRect(); var wr = editorWrap.getBoundingClientRect();
var top = wr.top + pt.y + 4; var top = wr.top + pt.y + 4;
var left = wr.left + pt.x - 10; var left = wr.left + pt.x - 10;
// Fallback if caret calc gives odd values // Clamp to viewport (never use textarea fallback)
if (top < 50) { var tr = ta.getBoundingClientRect(); top = tr.bottom + 6; left = tr.left + (tr.width / 2) - (bubble.offsetWidth / 2); } if (top < 60) top = 60;
if (top + 36 > window.innerHeight) top = top - 60; if (top + 40 > window.innerHeight - 10) top = window.innerHeight - 50;
if (left < 6) left = 6; if (left < 6) left = 6;
if (left + bubble.offsetWidth > window.innerWidth - 6) left = window.innerWidth - bubble.offsetWidth - 6; if (left + bubble.offsetWidth > window.innerWidth - 6) left = window.innerWidth - bubble.offsetWidth - 6;
bubble.style.left = left + 'px'; bubble.style.top = top + 'px'; bubble.style.left = left + 'px'; bubble.style.top = top + 'px';