// Roughly preserve reading position when entering the editor. // // While reading a page we record how far the center column is scrolled (as a // fraction of its scrollable height, keyed by path). When the same path opens // in the editor we restore that fraction, so you land near where you were // reading instead of at the top. It is fraction-based — the rendered page and // the raw-markdown editor have different heights — so the match is deliberately // approximate. This only moves the viewport; the caret default (end of doc) is // unchanged, so a click still decides where you actually edit. (function () { var center = document.querySelector('.center'); if (!center) return; var key = 'scrollsync:' + location.pathname; // Only restore a freshly-recorded position: a stale entry from earlier in // the tab session would jump a direct ?edit open to the wrong place. var MAX_AGE_MS = 5 * 60 * 1000; var params = new URLSearchParams(location.search); var inEditor = params.has('edit'); // Section / insert edits load only a slice of the document into the editor, // so a whole-page reading fraction does not map onto them — restore only for // a full-page ?edit. var fullPageEdit = inEditor && !params.has('section') && !params.has('insert_before'); function maxScroll() { return Math.max(0, center.scrollHeight - center.clientHeight); } if (inEditor) { if (!fullPageEdit) return; var raw = sessionStorage.getItem(key); if (!raw) return; var data; try { data = JSON.parse(raw); } catch (e) { return; } if (!data || typeof data.f !== 'number' || Date.now() - (data.t || 0) > MAX_AGE_MS) return; // Wait for CodeMirror to mount and the column to reach full height, then // map the fraction onto it. A double rAF after load lets CM's initial // layout and focus scroll settle so ours wins. window.addEventListener('load', function () { requestAnimationFrame(function () { requestAnimationFrame(function () { center.scrollTop = data.f * maxScroll(); }); }); }); return; } // Reading mode: keep the latest scroll fraction recorded (throttled to one // write per frame) so it is ready the moment the editor opens. var pending = false; center.addEventListener('scroll', function () { if (pending) return; pending = true; requestAnimationFrame(function () { pending = false; var m = maxScroll(); try { sessionStorage.setItem(key, JSON.stringify({ f: m > 0 ? center.scrollTop / m : 0, t: Date.now() })); } catch (e) {} }); }, { passive: true }); })();