mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-12 14:16:28 +03:00
fix(live): inject inline pre-restore script so scrollY wins vs browser
external live.js is fetched, so by the time it runs the browser has already queued its reload-scroll animation and history.scrollRestoration ='manual' has no effect. Inject a tiny inline synchronous <script> into the same block live-inject writes, BEFORE the external live.js tag. It sets scrollRestoration='manual' and does window.scrollTo(0, savedY) during HTML parse — before the browser can animate anywhere. 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
5e04a9f25a
commit
fb78ec4553
@@ -137,8 +137,18 @@ 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.
|
||||
// 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>';
|
||||
return (
|
||||
open + ' ' + MARKER_OPEN_TEXT + ' ' + close + '\n' +
|
||||
preRestore + '\n' +
|
||||
'<script src="http://localhost:' + port + '/live.js"></script>\n' +
|
||||
open + ' ' + MARKER_CLOSE_TEXT + ' ' + close + '\n'
|
||||
);
|
||||
|
||||
@@ -137,8 +137,18 @@ 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.
|
||||
// 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>';
|
||||
return (
|
||||
open + ' ' + MARKER_OPEN_TEXT + ' ' + close + '\n' +
|
||||
preRestore + '\n' +
|
||||
'<script src="http://localhost:' + port + '/live.js"></script>\n' +
|
||||
open + ' ' + MARKER_CLOSE_TEXT + ' ' + close + '\n'
|
||||
);
|
||||
|
||||
@@ -137,8 +137,18 @@ 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.
|
||||
// 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>';
|
||||
return (
|
||||
open + ' ' + MARKER_OPEN_TEXT + ' ' + close + '\n' +
|
||||
preRestore + '\n' +
|
||||
'<script src="http://localhost:' + port + '/live.js"></script>\n' +
|
||||
open + ' ' + MARKER_CLOSE_TEXT + ' ' + close + '\n'
|
||||
);
|
||||
|
||||
@@ -137,8 +137,18 @@ 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.
|
||||
// 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>';
|
||||
return (
|
||||
open + ' ' + MARKER_OPEN_TEXT + ' ' + close + '\n' +
|
||||
preRestore + '\n' +
|
||||
'<script src="http://localhost:' + port + '/live.js"></script>\n' +
|
||||
open + ' ' + MARKER_CLOSE_TEXT + ' ' + close + '\n'
|
||||
);
|
||||
|
||||
@@ -137,8 +137,18 @@ 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.
|
||||
// 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>';
|
||||
return (
|
||||
open + ' ' + MARKER_OPEN_TEXT + ' ' + close + '\n' +
|
||||
preRestore + '\n' +
|
||||
'<script src="http://localhost:' + port + '/live.js"></script>\n' +
|
||||
open + ' ' + MARKER_CLOSE_TEXT + ' ' + close + '\n'
|
||||
);
|
||||
|
||||
@@ -137,8 +137,18 @@ 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.
|
||||
// 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>';
|
||||
return (
|
||||
open + ' ' + MARKER_OPEN_TEXT + ' ' + close + '\n' +
|
||||
preRestore + '\n' +
|
||||
'<script src="http://localhost:' + port + '/live.js"></script>\n' +
|
||||
open + ' ' + MARKER_CLOSE_TEXT + ' ' + close + '\n'
|
||||
);
|
||||
|
||||
@@ -137,8 +137,18 @@ 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.
|
||||
// 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>';
|
||||
return (
|
||||
open + ' ' + MARKER_OPEN_TEXT + ' ' + close + '\n' +
|
||||
preRestore + '\n' +
|
||||
'<script src="http://localhost:' + port + '/live.js"></script>\n' +
|
||||
open + ' ' + MARKER_CLOSE_TEXT + ' ' + close + '\n'
|
||||
);
|
||||
|
||||
@@ -137,8 +137,18 @@ 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.
|
||||
// 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>';
|
||||
return (
|
||||
open + ' ' + MARKER_OPEN_TEXT + ' ' + close + '\n' +
|
||||
preRestore + '\n' +
|
||||
'<script src="http://localhost:' + port + '/live.js"></script>\n' +
|
||||
open + ' ' + MARKER_CLOSE_TEXT + ' ' + close + '\n'
|
||||
);
|
||||
|
||||
@@ -137,8 +137,18 @@ 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.
|
||||
// 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>';
|
||||
return (
|
||||
open + ' ' + MARKER_OPEN_TEXT + ' ' + close + '\n' +
|
||||
preRestore + '\n' +
|
||||
'<script src="http://localhost:' + port + '/live.js"></script>\n' +
|
||||
open + ' ' + MARKER_CLOSE_TEXT + ' ' + close + '\n'
|
||||
);
|
||||
|
||||
@@ -137,8 +137,18 @@ 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.
|
||||
// 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>';
|
||||
return (
|
||||
open + ' ' + MARKER_OPEN_TEXT + ' ' + close + '\n' +
|
||||
preRestore + '\n' +
|
||||
'<script src="http://localhost:' + port + '/live.js"></script>\n' +
|
||||
open + ' ' + MARKER_CLOSE_TEXT + ' ' + close + '\n'
|
||||
);
|
||||
|
||||
@@ -137,8 +137,18 @@ 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.
|
||||
// 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>';
|
||||
return (
|
||||
open + ' ' + MARKER_OPEN_TEXT + ' ' + close + '\n' +
|
||||
preRestore + '\n' +
|
||||
'<script src="http://localhost:' + port + '/live.js"></script>\n' +
|
||||
open + ' ' + MARKER_CLOSE_TEXT + ' ' + close + '\n'
|
||||
);
|
||||
|
||||
+24
-112
@@ -724,8 +724,9 @@
|
||||
|
||||
|
||||
|
||||
<!-- impeccable-variants-start 708145d6 -->
|
||||
<div data-impeccable-variants="708145d6" data-impeccable-variant-count="3" style="display: contents">
|
||||
|
||||
<!-- impeccable-variants-start 32275091 -->
|
||||
<div data-impeccable-variants="32275091" data-impeccable-variant-count="3" style="display: contents">
|
||||
<!-- Original -->
|
||||
<div data-impeccable-variant="original">
|
||||
<div class="consulting-text">
|
||||
@@ -734,118 +735,27 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- Variants: insert below this line -->
|
||||
<style data-impeccable-css="708145d6">
|
||||
<style data-impeccable-css="32275091">
|
||||
@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);
|
||||
}
|
||||
.v1-title {
|
||||
font-family: var(--font-display);
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
font-size: clamp(2.75rem, 5.5vw, 4rem);
|
||||
line-height: 1;
|
||||
color: var(--color-ink);
|
||||
margin: 0;
|
||||
}
|
||||
.v1-body {
|
||||
font-family: var(--font-body);
|
||||
font-size: 1rem;
|
||||
line-height: 1.6;
|
||||
color: var(--color-charcoal);
|
||||
margin: 4px 0 0;
|
||||
}
|
||||
.v1-body a {
|
||||
color: var(--color-ink);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 3px;
|
||||
text-decoration-color: var(--color-accent);
|
||||
}
|
||||
.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); }
|
||||
.v1-title { font-family: var(--font-display); font-style: italic; font-weight: 300; font-size: clamp(2.75rem, 5.5vw, 4rem); line-height: 1; color: var(--color-ink); margin: 0; }
|
||||
.v1-body { font-family: var(--font-body); font-size: 1rem; line-height: 1.6; color: var(--color-charcoal); margin: 4px 0 0; }
|
||||
.v1-body a { color: var(--color-ink); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--color-accent); }
|
||||
}
|
||||
@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-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;
|
||||
}
|
||||
.v2-body a {
|
||||
color: var(--color-ink);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 3px;
|
||||
text-decoration-color: var(--color-accent);
|
||||
}
|
||||
.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-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; }
|
||||
.v2-body a { color: var(--color-ink); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--color-accent); }
|
||||
}
|
||||
@scope ([data-impeccable-variant="3"]) {
|
||||
.consulting-text {
|
||||
display: grid;
|
||||
gap: 32px;
|
||||
max-width: 54ch;
|
||||
}
|
||||
.v3-title {
|
||||
font-family: var(--font-display);
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
font-size: clamp(4rem, 8vw, 6rem);
|
||||
line-height: 0.9;
|
||||
color: var(--color-ink);
|
||||
margin: 0;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
.v3-body {
|
||||
font-family: var(--font-body);
|
||||
font-size: 1rem;
|
||||
line-height: 1.65;
|
||||
color: var(--color-charcoal);
|
||||
margin: 0;
|
||||
padding-left: 20px;
|
||||
border-left: 1px solid var(--color-accent);
|
||||
}
|
||||
.v3-body a {
|
||||
color: var(--color-ink);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 3px;
|
||||
text-decoration-color: var(--color-accent);
|
||||
}
|
||||
.consulting-text { display: grid; gap: 32px; max-width: 54ch; }
|
||||
.v3-title { font-family: var(--font-display); font-style: italic; font-weight: 300; font-size: clamp(4rem, 8vw, 6rem); line-height: 0.9; color: var(--color-ink); margin: 0; letter-spacing: -0.02em; }
|
||||
.v3-body { font-family: var(--font-body); font-size: 1rem; line-height: 1.65; color: var(--color-charcoal); margin: 0; padding-left: 20px; border-left: 1px solid var(--color-accent); }
|
||||
.v3-body a { color: var(--color-ink); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--color-accent); }
|
||||
}
|
||||
</style>
|
||||
<div data-impeccable-variant="1">
|
||||
@@ -860,18 +770,19 @@
|
||||
<span class="v2-mark">¶</span>
|
||||
<div class="v2-body">
|
||||
<h2 class="v2-title">Work with me.</h2>
|
||||
<p>Impeccable is built by <a href="https://renaissance-geek.ai" target="_blank" rel="noopener">Renaissance Geek</a>. I work with enterprise teams on rollouts, integrations, and training.</p>
|
||||
<p>Impeccable is built by <a href="https://renaissance-geek.ai" target="_blank" rel="noopener">Renaissance Geek</a>. Rollouts, integrations, training.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-impeccable-variant="3" style="display: none">
|
||||
<div class="consulting-text">
|
||||
<h2 class="v3-title">Work <br>with me.</h2>
|
||||
<p class="v3-body">Impeccable is built by <a href="https://renaissance-geek.ai" target="_blank" rel="noopener">Renaissance Geek</a>. I work with enterprise teams on large-scale rollouts, custom integrations, and training for designers and developers.</p>
|
||||
<p class="v3-body">Impeccable is built by <a href="https://renaissance-geek.ai" target="_blank" rel="noopener">Renaissance Geek</a>. Large-scale rollouts, custom integrations, and training for teams raising the bar on AI-generated design.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- impeccable-variants-end 708145d6 -->
|
||||
<!-- impeccable-variants-end 32275091 -->
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -921,6 +832,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 src="http://localhost:8400/live.js"></script>
|
||||
<!-- impeccable-live-end -->
|
||||
</body>
|
||||
|
||||
@@ -78,6 +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 src="http://localhost:8400/live.js"></script>
|
||||
<!-- impeccable-live-end -->
|
||||
</body>
|
||||
|
||||
@@ -137,8 +137,18 @@ 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.
|
||||
// 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>';
|
||||
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