From c58d13eafa76b9be34a00d888fde41c4da7c222b Mon Sep 17 00:00:00 2001 From: Fabio Montefuscolo Date: Mon, 3 Aug 2026 22:13:01 +0200 Subject: [PATCH] feat: focus editor and restore caret/scroll on note load --- openspec/changes/sidepanel-ux-improvements/tasks.md | 2 +- sidepanel/sidepanel.js | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/openspec/changes/sidepanel-ux-improvements/tasks.md b/openspec/changes/sidepanel-ux-improvements/tasks.md index d8a92ce..b2e0710 100644 --- a/openspec/changes/sidepanel-ux-improvements/tasks.md +++ b/openspec/changes/sidepanel-ux-improvements/tasks.md @@ -13,7 +13,7 @@ ## 3. Focus and caret/scroll restore -- [ ] 3.1 In `loadNoteForTab`, after setting `editor.value`, restore caret via `setSelectionRange` with offsets clamped to content length (default 0 for legacy records), restore `scrollTop` (in `requestAnimationFrame` if layout timing clamps it), and call `editor.focus()` +- [x] 3.1 In `loadNoteForTab`, after setting `editor.value`, restore caret via `setSelectionRange` with offsets clamped to content length (default 0 for legacy records), restore `scrollTop` (in `requestAnimationFrame` if layout timing clamps it), and call `editor.focus()` - [ ] 3.2 Make `reloadFromDB` skip the `editor.value` assignment when fetched content is identical, so remote saves never move the local caret unnecessarily - [ ] 3.3 Manually verify focus lands when the panel opens via toolbar action and via keyboard shortcut; caret restore works on panel open, tab switch, and SPA navigation diff --git a/sidepanel/sidepanel.js b/sidepanel/sidepanel.js index ddd8174..301643a 100644 --- a/sidepanel/sidepanel.js +++ b/sidepanel/sidepanel.js @@ -100,6 +100,19 @@ async function loadNoteForTab(tabId) { editor.value = note ? note.content : ''; isLoadingContent = false; + // Restore caret and scroll position, clamped to the current content + // length (another panel may have shortened the note since the position + // was saved). Records saved before caret persistence default to 0. + const len = editor.value.length; + const start = Math.min(note?.caretStart ?? 0, len); + const end = Math.min(note?.caretEnd ?? start, len); + editor.setSelectionRange(start, end); + const savedScrollTop = note?.scrollTop ?? 0; + requestAnimationFrame(() => { + editor.scrollTop = savedScrollTop; + }); + editor.focus(); + updateStatus('Saved'); } catch (err) { console.error('Side Notes: failed to load note for tab', tabId, err);