fix(ui): clear session search on boot + autocomplete=off + pageshow bfcache handler (closes #822)

* fix(ui): clear session search on boot + autocomplete=off — prevents bfcache from restoring stale filter (closes #822)

* fix(ui): add pageshow handler for true bfcache restore case (#822 completion)

The original PR's two fixes cover fresh page loads and hard reloads —
but the bug the issue describes happens on *bfcache restore* (Chrome's
back-forward cache).  The async boot IIFE does NOT re-run when the
browser restores a page from bfcache; the DOM is restored in place,
including any stale #sessionSearch value.  The boot-time clear has no
effect there.

`autocomplete="off"` is a hint that Chrome and others sometimes honour
for bfcache but is not reliable for user-typed values (as opposed to
autofill candidates).

Add a pageshow event listener that checks event.persisted === true and,
on that path only, clears #sessionSearch and re-renders from cache.
Fresh loads skip the listener (persisted=false) and continue to be
handled by the boot IIFE.

Also added tests/test_session_search_bfcache_822.py with 7 tests:
- autocomplete="off" present on the input
- boot-time clear runs before the first renderSessionList
- pageshow listener registered
- handler guards on event.persisted
- handler clears the search field and triggers a re-render

Full suite: 1745 passed, 0 failures.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
Co-authored-by: Nathan Esquenazi <nesquena@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
nesquena-hermes
2026-04-21 22:11:32 -07:00
committed by GitHub
parent d4a3adb7b1
commit 880085a09e
4 changed files with 167 additions and 1 deletions

View File

@@ -829,6 +829,11 @@ function applyBotName(){
_initResizePanels();
// Workspace panel restore happens AFTER loadSession so we know if
// the session has a workspace — prevents the snap-open-then-closed flash (#576).
// Fix #822: clear any browser-restored value before first render. This
// covers fresh page loads and reloads. The bfcache restore case is handled
// separately below by a `pageshow` listener — the async IIFE here does NOT
// re-run when the browser restores the page from bfcache.
const _srch = document.getElementById('sessionSearch'); if (_srch) _srch.value = '';
const saved=localStorage.getItem('hermes-webui-session');
if(saved){
try{
@@ -851,3 +856,18 @@ function applyBotName(){
// Start real-time gateway session sync if setting is enabled
if(typeof startGatewaySSE==='function') startGatewaySSE();
})();
// Fix #822 (bfcache path): when the browser restores the page from the
// back-forward cache, the async boot IIFE above does NOT re-run, but the
// DOM — including any stale value in #sessionSearch — IS restored. A
// prior search string would silently hide all sessions via the filter in
// renderSessionListFromCache(). Clear the field and re-render whenever
// the page is restored from cache (`event.persisted === true`).
window.addEventListener('pageshow', (event) => {
if (!event.persisted) return; // fresh loads are handled by the IIFE above
const _srch = document.getElementById('sessionSearch');
if (_srch) _srch.value = '';
if (typeof renderSessionListFromCache === 'function') {
try { renderSessionListFromCache(); } catch (_) {}
}
});

View File

@@ -40,7 +40,7 @@
<span data-i18n="new_conversation">New conversation</span> <span style="font-size:10px;opacity:.5;margin-left:4px">Cmd+K</span>
</button>
</div>
<div class="session-search"><input id="sessionSearch" placeholder="Filter conversations..." data-i18n-placeholder="filter_conversations" oninput="filterSessions()"></div>
<div class="session-search"><input id="sessionSearch" placeholder="Filter conversations..." data-i18n-placeholder="filter_conversations" oninput="filterSessions()" autocomplete="off"></div>
<div class="session-list" id="sessionList"></div>
</div>
<!-- Tasks (cron) panel -->