Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions sidebar-scroll.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
(function () {
if (typeof window === "undefined") return;

var KEY = "kernel-docs-sidebar-scroll";

function findSidebar() {
var candidates = document.querySelectorAll(
"aside, nav[aria-label='Sidebar'], aside[aria-label='Sidebar'], #sidebar"
);
Comment on lines +7 to +9
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Prefer the documented scrollable sidebar element

Mintlify documents #sidebar-content as the scrollable content area inside the sidebar, but this selector only considers the outer containers. On pages where the user actually scrolls #sidebar-content, save() records the outer #sidebar/aside scrollTop (typically 0) or finds nothing, so deep API/sidebar navigation still resets instead of restoring the position. Include and prefer #sidebar-content before the container selectors so the saved value comes from the element that receives the scroll.

Useful? React with 👍 / 👎.

for (var i = 0; i < candidates.length; i++) {
var el = candidates[i];
if (el.scrollHeight > el.clientHeight + 1) return el;
}
return null;
}

function save() {
var sb = findSidebar();
if (sb) {
try { sessionStorage.setItem(KEY, String(sb.scrollTop)); } catch (e) {}
}
}

function restore() {
var sb = findSidebar();
if (!sb) return false;
var raw;
try { raw = sessionStorage.getItem(KEY); } catch (e) { return false; }
if (raw === null) return false;
var top = parseInt(raw, 10);
if (isNaN(top)) return false;
if (Math.abs(sb.scrollTop - top) > 1) sb.scrollTop = top;
return true;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restore reports success prematurely

Medium Severity

After navigation, restore always returns success once a saved value exists and a sidebar node is found, even when scrollTop could not be set to the stored offset. pollRestore then stops retrying, so a sidebar that is not yet scrollable can stay at the top once content finishes laying out.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 34326a0. Configure here.


var saveTimer;
document.addEventListener(
"scroll",
function (e) {
var sb = findSidebar();
if (!sb) return;
var t = e.target;
if (t === sb || (t.contains && t.contains(sb)) || sb.contains(t)) {
clearTimeout(saveTimer);
saveTimer = setTimeout(save, 80);
}
},
true
);

document.addEventListener(
"click",
function (e) {
if (e.target && e.target.closest && e.target.closest("a")) save();
},
true
);

function pollRestore() {
var attempts = 0;
var iv = setInterval(function () {
attempts++;
if (restore() || attempts > 30) clearInterval(iv);
}, 50);
}

var origPush = history.pushState;
history.pushState = function () {
var r = origPush.apply(this, arguments);
pollRestore();
return r;
};
var origReplace = history.replaceState;
history.replaceState = function () {
var r = origReplace.apply(this, arguments);
pollRestore();
return r;
};
window.addEventListener("popstate", pollRestore);

if (document.readyState === "complete") {
pollRestore();
} else {
window.addEventListener("load", pollRestore);
}
})();
Loading