Fix scroll restore on refresh, add CLAUDE.md bundle compile directive
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -666,7 +666,10 @@ class Rsx {
|
|||||||
Rsx.trigger('_debug_ready');
|
Rsx.trigger('_debug_ready');
|
||||||
|
|
||||||
// Restore scroll position on page refresh
|
// Restore scroll position on page refresh
|
||||||
Rsx._restore_scroll_on_refresh();
|
// Use requestAnimationFrame to ensure DOM is fully rendered after SPA action completes
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
Rsx._restore_scroll_on_refresh();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -694,6 +697,7 @@ class Rsx {
|
|||||||
y: window.scrollY
|
y: window.scrollY
|
||||||
};
|
};
|
||||||
sessionStorage.setItem(Rsx._SCROLL_STORAGE_KEY, JSON.stringify(scroll_data));
|
sessionStorage.setItem(Rsx._SCROLL_STORAGE_KEY, JSON.stringify(scroll_data));
|
||||||
|
console.log('[Rsx Scroll] Saved:', scroll_data.x, scroll_data.y, 'for', scroll_data.url);
|
||||||
}, 100); // 100ms debounce
|
}, 100); // 100ms debounce
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -703,40 +707,61 @@ class Rsx {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
static _restore_scroll_on_refresh() {
|
static _restore_scroll_on_refresh() {
|
||||||
|
console.log('[Rsx Scroll] _restore_scroll_on_refresh called');
|
||||||
|
|
||||||
// Set up scroll listener to continuously save position
|
// Set up scroll listener to continuously save position
|
||||||
window.addEventListener('scroll', Rsx._save_scroll_position, { passive: true });
|
window.addEventListener('scroll', Rsx._save_scroll_position, { passive: true });
|
||||||
|
console.log('[Rsx Scroll] Scroll listener attached');
|
||||||
|
|
||||||
// Check if this is a page refresh using Performance API
|
// Check if this is a page refresh using Performance API
|
||||||
const nav_entries = performance.getEntriesByType('navigation');
|
const nav_entries = performance.getEntriesByType('navigation');
|
||||||
if (nav_entries.length === 0) return;
|
console.log('[Rsx Scroll] Navigation entries:', nav_entries.length);
|
||||||
|
if (nav_entries.length === 0) {
|
||||||
|
console.log('[Rsx Scroll] No navigation entries found, skipping restore');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const nav_type = nav_entries[0].type;
|
const nav_type = nav_entries[0].type;
|
||||||
if (nav_type !== 'reload') return;
|
console.log('[Rsx Scroll] Navigation type:', nav_type);
|
||||||
|
if (nav_type !== 'reload') {
|
||||||
|
console.log('[Rsx Scroll] Not a reload (type=' + nav_type + '), skipping restore');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// This is a refresh - try to restore scroll position
|
// This is a refresh - try to restore scroll position
|
||||||
const stored = sessionStorage.getItem(Rsx._SCROLL_STORAGE_KEY);
|
const stored = sessionStorage.getItem(Rsx._SCROLL_STORAGE_KEY);
|
||||||
if (!stored) return;
|
console.log('[Rsx Scroll] Stored scroll data:', stored);
|
||||||
|
if (!stored) {
|
||||||
|
console.log('[Rsx Scroll] No stored scroll position found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const scroll_data = JSON.parse(stored);
|
const scroll_data = JSON.parse(stored);
|
||||||
const current_url = window.location.pathname + window.location.search;
|
const current_url = window.location.pathname + window.location.search;
|
||||||
|
console.log('[Rsx Scroll] Stored URL:', scroll_data.url, 'Current URL:', current_url);
|
||||||
|
|
||||||
// Only restore if URL matches
|
// Only restore if URL matches
|
||||||
if (scroll_data.url !== current_url) return;
|
if (scroll_data.url !== current_url) {
|
||||||
|
console.log('[Rsx Scroll] URL mismatch, skipping restore');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Restore scroll position instantly
|
// Restore scroll position instantly
|
||||||
|
console.log('[Rsx Scroll] Restoring scroll to:', scroll_data.x, scroll_data.y);
|
||||||
window.scrollTo({
|
window.scrollTo({
|
||||||
left: scroll_data.x,
|
left: scroll_data.x,
|
||||||
top: scroll_data.y,
|
top: scroll_data.y,
|
||||||
behavior: 'instant'
|
behavior: 'instant'
|
||||||
});
|
});
|
||||||
|
|
||||||
console_debug('Rsx', `Restored scroll position on refresh: ${scroll_data.x}, ${scroll_data.y}`);
|
console.log('[Rsx Scroll] Restored scroll position on refresh:', scroll_data.x, scroll_data.y);
|
||||||
|
|
||||||
// Clear stored position after successful restore
|
// Clear stored position after successful restore
|
||||||
sessionStorage.removeItem(Rsx._SCROLL_STORAGE_KEY);
|
sessionStorage.removeItem(Rsx._SCROLL_STORAGE_KEY);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Invalid JSON or other error - ignore
|
// Invalid JSON or other error - ignore
|
||||||
|
console.log('[Rsx Scroll] Error restoring scroll:', e.message);
|
||||||
sessionStorage.removeItem(Rsx._SCROLL_STORAGE_KEY);
|
sessionStorage.removeItem(Rsx._SCROLL_STORAGE_KEY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -682,8 +682,15 @@ class Spa {
|
|||||||
window.scrollTo({ left: opts.scroll.x, top: opts.scroll.y, behavior: 'instant' });
|
window.scrollTo({ left: opts.scroll.x, top: opts.scroll.y, behavior: 'instant' });
|
||||||
} else if (opts.scroll === undefined) {
|
} else if (opts.scroll === undefined) {
|
||||||
// Default: scroll to top for new navigation (only if scroll not explicitly set)
|
// Default: scroll to top for new navigation (only if scroll not explicitly set)
|
||||||
console_debug('Spa', 'Scrolling to top (new navigation)');
|
// BUT skip on page reload - let Rsx._restore_scroll_on_refresh handle it
|
||||||
window.scrollTo({ left: 0, top: 0, behavior: 'instant' });
|
const nav_entries = performance.getEntriesByType('navigation');
|
||||||
|
const is_reload = nav_entries.length > 0 && nav_entries[0].type === 'reload';
|
||||||
|
if (is_reload) {
|
||||||
|
console_debug('Spa', 'Skipping scroll-to-top on page reload (Rsx handles refresh scroll restore)');
|
||||||
|
} else {
|
||||||
|
console_debug('Spa', 'Scrolling to top (new navigation)');
|
||||||
|
window.scrollTo({ left: 0, top: 0, behavior: 'instant' });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// If opts.scroll === null, don't scroll (let Navigation API or browser handle it)
|
// If opts.scroll === null, don't scroll (let Navigation API or browser handle it)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user