mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-12 14:16:28 +03:00
fix(live): retry inline scroll-restore on fonts.ready and load
scrollTo(y) clamps to the current document.scrollHeight, which is several hundred pixels short of the final value until async-loaded fonts swap in (Cormorant Garamond italic grew consulting-section layout by ~585px in the logs). The initial synchronous scroll was clamping to ~6165 even though the Go-time target was 6749.5. Retry on document.fonts.ready and on the window load event, both of which fire once the document reaches its final height. 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
fb78ec4553
commit
f0f2935547
@@ -138,14 +138,23 @@ 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*
|
||||
// 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))window.scrollTo(0,y);}catch(e){}})();</script>';
|
||||
'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' +
|
||||
|
||||
@@ -138,14 +138,23 @@ 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*
|
||||
// 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))window.scrollTo(0,y);}catch(e){}})();</script>';
|
||||
'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' +
|
||||
|
||||
@@ -138,14 +138,23 @@ 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*
|
||||
// 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))window.scrollTo(0,y);}catch(e){}})();</script>';
|
||||
'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' +
|
||||
|
||||
@@ -138,14 +138,23 @@ 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*
|
||||
// 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))window.scrollTo(0,y);}catch(e){}})();</script>';
|
||||
'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' +
|
||||
|
||||
@@ -138,14 +138,23 @@ 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*
|
||||
// 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))window.scrollTo(0,y);}catch(e){}})();</script>';
|
||||
'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' +
|
||||
|
||||
@@ -138,14 +138,23 @@ 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*
|
||||
// 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))window.scrollTo(0,y);}catch(e){}})();</script>';
|
||||
'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' +
|
||||
|
||||
@@ -138,14 +138,23 @@ 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*
|
||||
// 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))window.scrollTo(0,y);}catch(e){}})();</script>';
|
||||
'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' +
|
||||
|
||||
@@ -138,14 +138,23 @@ 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*
|
||||
// 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))window.scrollTo(0,y);}catch(e){}})();</script>';
|
||||
'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' +
|
||||
|
||||
@@ -138,14 +138,23 @@ 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*
|
||||
// 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))window.scrollTo(0,y);}catch(e){}})();</script>';
|
||||
'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' +
|
||||
|
||||
@@ -138,14 +138,23 @@ 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*
|
||||
// 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))window.scrollTo(0,y);}catch(e){}})();</script>';
|
||||
'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' +
|
||||
|
||||
@@ -138,14 +138,23 @@ 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*
|
||||
// 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))window.scrollTo(0,y);}catch(e){}})();</script>';
|
||||
'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' +
|
||||
|
||||
+8
-6
@@ -725,8 +725,9 @@
|
||||
|
||||
|
||||
|
||||
<!-- impeccable-variants-start 32275091 -->
|
||||
<div data-impeccable-variants="32275091" data-impeccable-variant-count="3" style="display: contents">
|
||||
|
||||
<!-- impeccable-variants-start f3c91105 -->
|
||||
<div data-impeccable-variants="f3c91105" data-impeccable-variant-count="3" style="display: contents">
|
||||
<!-- Original -->
|
||||
<div data-impeccable-variant="original">
|
||||
<div class="consulting-text">
|
||||
@@ -735,7 +736,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- Variants: insert below this line -->
|
||||
<style data-impeccable-css="32275091">
|
||||
<style data-impeccable-css="f3c91105">
|
||||
@scope ([data-impeccable-variant="1"]) {
|
||||
.consulting-text { display: grid; gap: 14px; max-width: 56ch; }
|
||||
.v1-tag { font-family: var(--font-mono); font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.25em; color: var(--color-accent); }
|
||||
@@ -745,7 +746,7 @@
|
||||
}
|
||||
@scope ([data-impeccable-variant="2"]) {
|
||||
.consulting-text { display: flex; align-items: baseline; gap: 28px; padding: 20px 0; border-block: 1px solid var(--color-ink); }
|
||||
.v2-mark { font-family: var(--font-display); font-style: italic; font-weight: 400; font-size: 3rem; line-height: 0.9; color: var(--color-accent); }
|
||||
.v2-mark { font-family: var(--font-display); font-style: italic; font-size: 3rem; line-height: 0.9; color: var(--color-accent); }
|
||||
.v2-body { display: flex; flex-direction: column; gap: 8px; max-width: 52ch; }
|
||||
.v2-title { font-family: var(--font-display); font-style: italic; font-size: 1.875rem; line-height: 1.15; color: var(--color-ink); margin: 0; }
|
||||
.v2-body p { font-family: var(--font-body); font-size: 0.9375rem; line-height: 1.6; color: var(--color-charcoal); margin: 0; }
|
||||
@@ -781,7 +782,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- impeccable-variants-end 32275091 -->
|
||||
<!-- impeccable-variants-end f3c91105 -->
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -832,7 +834,7 @@
|
||||
<script type="module" src="./app.js"></script>
|
||||
|
||||
<!-- impeccable-live-start -->
|
||||
<script>(function(){try{history.scrollRestoration="manual";var y=parseFloat(localStorage.getItem("impeccable-live-session-scroll"));if(isFinite(y))window.scrollTo(0,y);}catch(e){}})();</script>
|
||||
<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>
|
||||
<script src="http://localhost:8400/live.js"></script>
|
||||
<!-- impeccable-live-end -->
|
||||
</body>
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@
|
||||
<p>Questions about this policy? Open an issue on <a href="https://github.com/pbakaus/impeccable">GitHub</a> or reach out to <a href="https://x.com/pbakaus">@pbakaus</a>.</p>
|
||||
</main>
|
||||
<!-- impeccable-live-start -->
|
||||
<script>(function(){try{history.scrollRestoration="manual";var y=parseFloat(localStorage.getItem("impeccable-live-session-scroll"));if(isFinite(y))window.scrollTo(0,y);}catch(e){}})();</script>
|
||||
<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>
|
||||
<script src="http://localhost:8400/live.js"></script>
|
||||
<!-- impeccable-live-end -->
|
||||
</body>
|
||||
|
||||
@@ -138,14 +138,23 @@ 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*
|
||||
// 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))window.scrollTo(0,y);}catch(e){}})();</script>';
|
||||
'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' +
|
||||
|
||||
Reference in New Issue
Block a user