diff --git a/app/RSpade/Core/Js/Rsx.js b/app/RSpade/Core/Js/Rsx.js index 3733cbac1..dc4f56d08 100755 --- a/app/RSpade/Core/Js/Rsx.js +++ b/app/RSpade/Core/Js/Rsx.js @@ -664,6 +664,81 @@ class Rsx { // DO NOT use this in application code - use on_app_ready() phase instead // This event exists solely for debugging tools that need to run after full initialization Rsx.trigger('_debug_ready'); + + // Restore scroll position on page refresh + Rsx._restore_scroll_on_refresh(); + } + + /** + * Storage key for scroll position in sessionStorage + * @private + */ + static _SCROLL_STORAGE_KEY = 'rsx_scroll_pos'; + + /** + * Save scroll position to sessionStorage on scroll (debounced) + * Called from scroll event listener set up in _restore_scroll_on_refresh + * @private + */ + static _scroll_save_timeout = null; + static _save_scroll_position() { + // Debounce: cancel pending save and schedule fresh one + if (Rsx._scroll_save_timeout) { + clearTimeout(Rsx._scroll_save_timeout); + } + + Rsx._scroll_save_timeout = setTimeout(() => { + const scroll_data = { + url: window.location.pathname + window.location.search, + x: window.scrollX, + y: window.scrollY + }; + sessionStorage.setItem(Rsx._SCROLL_STORAGE_KEY, JSON.stringify(scroll_data)); + }, 100); // 100ms debounce + } + + /** + * Restore scroll position if this is a page refresh + * Uses Performance API to detect reload navigation type + * @private + */ + static _restore_scroll_on_refresh() { + // Set up scroll listener to continuously save position + window.addEventListener('scroll', Rsx._save_scroll_position, { passive: true }); + + // Check if this is a page refresh using Performance API + const nav_entries = performance.getEntriesByType('navigation'); + if (nav_entries.length === 0) return; + + const nav_type = nav_entries[0].type; + if (nav_type !== 'reload') return; + + // This is a refresh - try to restore scroll position + const stored = sessionStorage.getItem(Rsx._SCROLL_STORAGE_KEY); + if (!stored) return; + + try { + const scroll_data = JSON.parse(stored); + const current_url = window.location.pathname + window.location.search; + + // Only restore if URL matches + if (scroll_data.url !== current_url) return; + + // Restore scroll position instantly + window.scrollTo({ + left: scroll_data.x, + top: scroll_data.y, + behavior: 'instant' + }); + + console_debug('Rsx', `Restored scroll position on refresh: ${scroll_data.x}, ${scroll_data.y}`); + + // Clear stored position after successful restore + sessionStorage.removeItem(Rsx._SCROLL_STORAGE_KEY); + } catch (e) { + // Invalid JSON or other error - ignore + sessionStorage.removeItem(Rsx._SCROLL_STORAGE_KEY); + } } /* Calling this stops the boot process. */