From d19f893b12bfa35b502e83580daa784109b73e54 Mon Sep 17 00:00:00 2001 From: CosmosJ0618 Date: Tue, 30 Jun 2026 23:57:10 +0800 Subject: [PATCH] Marks: fix local marks not restoring position in SPAs Fix an issue where local marks fail to jump correctly on modern sites (like Twitter/Reddit) that use internal divs instead of the window for scrolling. Marks now save and restore the scroll position of the inner active element. --- content_scripts/marks.js | 22 +++++++++++++++++++++- content_scripts/scroller.js | 8 ++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/content_scripts/marks.js b/content_scripts/marks.js index 0e08d3b15..d967ba24d 100644 --- a/content_scripts/marks.js +++ b/content_scripts/marks.js @@ -20,9 +20,20 @@ const Marks = { }, getMarkString() { + let localScrollX = 0; + let localScrollY = 0; + if (globalThis.Scroller) { + const scrollableEl = Scroller.activeElement(); + if (scrollableEl) { + localScrollX = scrollableEl.scrollLeft; + localScrollY = scrollableEl.scrollTop; + } + } return JSON.stringify({ scrollX: globalThis.scrollX, scrollY: globalThis.scrollY, + localScrollX, + localScrollY, hash: globalThis.location.hash, }); }, @@ -117,10 +128,19 @@ const Marks = { if (markString != null) { this.setPreviousPosition(); const position = JSON.parse(markString); - if (position.hash && (position.scrollX === 0) && (position.scrollY === 0)) { + if (position.hash && (position.scrollX === 0) && (position.scrollY === 0) && !position.localScrollX && !position.localScrollY) { globalThis.location.hash = position.hash; } else { globalThis.scrollTo(position.scrollX, position.scrollY); + if ("localScrollX" in position) { + if (globalThis.Scroller) { + const scrollableEl = Scroller.activeElement(); + if (scrollableEl) { + scrollableEl.scrollLeft = position.localScrollX; + scrollableEl.scrollTop = position.localScrollY; + } + } + } } this.showMessage("Jumped to local mark", keyChar); } else { diff --git a/content_scripts/scroller.js b/content_scripts/scroller.js index 5501ed0a7..f1df7cebe 100644 --- a/content_scripts/scroller.js +++ b/content_scripts/scroller.js @@ -450,6 +450,14 @@ const Scroller = { } } }, + + activeElement() { + if (!activatedElement || !document.body.contains(activatedElement)) { + activatedElement = (getScrollingElement() && firstScrollableElement()) || + getScrollingElement(); + } + return activatedElement; + }, }; const getSpecialScrollingElement = function () {