mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-15 23:56:29 +03:00
refactor(live): move scroll-restore out of injected inline back into live.js
The inline pre-restore wasn't actually fixing a timing issue — the fix was the fonts.ready + load retries. Since live.js's own top-level block runs before DOMContentLoaded and we can do the same retries there, we don't need an inline script injected into every user page. Simpler HTML, single source of truth. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
f0f2935547
commit
bd86147d70
@@ -121,15 +121,23 @@
|
||||
}
|
||||
|
||||
// Pre-empt the browser: apply manual scroll restoration and jump to the
|
||||
// saved scrollY at script-parse time (before DOMContentLoaded). If we
|
||||
// wait until init(), the browser has already begun animating its own
|
||||
// restore — especially bad when `scroll-behavior: smooth` is set on html.
|
||||
// saved scrollY at script-parse time. Retries on fonts.ready and load
|
||||
// are essential: scrollTo(y) clamps to the current document.scrollHeight,
|
||||
// which is often hundreds of pixels short of the final value until
|
||||
// async-loaded fonts swap in and reflow.
|
||||
try {
|
||||
history.scrollRestoration = 'manual';
|
||||
const savedY = readScrollY();
|
||||
if (savedY != null && Math.abs(window.scrollY - savedY) > 0.5) {
|
||||
console.log('[impeccable.scroll] early restore', { from: window.scrollY, to: savedY });
|
||||
window.scrollTo({ top: savedY, left: 0, behavior: 'instant' });
|
||||
if (savedY != null) {
|
||||
const apply = () => {
|
||||
if (Math.abs(window.scrollY - savedY) > 0.5) {
|
||||
console.log('[impeccable.scroll] early restore', { from: window.scrollY, to: savedY });
|
||||
window.scrollTo(0, savedY);
|
||||
}
|
||||
};
|
||||
apply();
|
||||
if (document.fonts?.ready) document.fonts.ready.then(apply).catch(() => {});
|
||||
window.addEventListener('load', apply, { once: true });
|
||||
}
|
||||
} catch {}
|
||||
|
||||
|
||||
@@ -137,27 +137,8 @@ function commentClose(syntax) { return syntax === 'jsx' ? '*/}' : '-->'; }
|
||||
function buildTagBlock(syntax, port) {
|
||||
const open = commentOpen(syntax);
|
||||
const close = commentClose(syntax);
|
||||
// Inline pre-restore: runs before the external live.js is fetched. Sets
|
||||
// scrollRestoration='manual' and jumps to the saved scrollY synchronously
|
||||
// during HTML parse, beating the browser's animated reload-restore.
|
||||
//
|
||||
// Retries on fonts.ready and load are essential: scrollTo(y) clamps to
|
||||
// the document's current scrollHeight, which is often hundreds of
|
||||
// pixels short of the final value until async-loaded fonts swap in.
|
||||
// Hardcoded key matches live-browser.js: PREFIX ('impeccable-live') +
|
||||
// LS_KEY suffix ('-session') + SCROLL_KEY_SUFFIX ('-scroll').
|
||||
const preRestore =
|
||||
'<script>(function(){try{history.scrollRestoration="manual";' +
|
||||
'var y=parseFloat(localStorage.getItem("impeccable-live-session-scroll"));' +
|
||||
'if(!isFinite(y))return;' +
|
||||
'var apply=function(){if(Math.abs(window.scrollY-y)>0.5)window.scrollTo(0,y);};' +
|
||||
'apply();' +
|
||||
'if(document.fonts&&document.fonts.ready)document.fonts.ready.then(apply);' +
|
||||
'window.addEventListener("load",apply,{once:true});' +
|
||||
'}catch(e){}})();</script>';
|
||||
return (
|
||||
open + ' ' + MARKER_OPEN_TEXT + ' ' + close + '\n' +
|
||||
preRestore + '\n' +
|
||||
'<script src="http://localhost:' + port + '/live.js"></script>\n' +
|
||||
open + ' ' + MARKER_CLOSE_TEXT + ' ' + close + '\n'
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user