Global hash strip: suppress re-scan on anchor-only URL changes
This commit is contained in:
+26
-2
@@ -639,24 +639,42 @@ async function persistTabResult(tab, result) {
|
||||
} catch {}
|
||||
}
|
||||
|
||||
// URL fragment (hash) never affects server response or our ID extraction. Strip it
|
||||
// when comparing URLs so in-page anchor jumps (e.g. `#gallery-1`, `#gallery-2`) don't
|
||||
// invalidate the tab cache or re-trigger scans. See exoticaz.to gallery navigation.
|
||||
function stripHash(url) {
|
||||
if (typeof url !== "string") return url;
|
||||
const i = url.indexOf("#");
|
||||
return i === -1 ? url : url.slice(0, i);
|
||||
}
|
||||
|
||||
// Tracks the last full URL we saw per tab so we can detect hash-only changes
|
||||
// (which Chrome still reports via `chrome.tabs.onUpdated` with `changeInfo.url`).
|
||||
const tabLastUrl = new Map(); // tabId -> last full url seen
|
||||
|
||||
async function getTabResult(tab) {
|
||||
if (!tab || tab.id == null) return null;
|
||||
try {
|
||||
const got = await chrome.storage.session.get(tabCacheKey(tab.id));
|
||||
const entry = got[tabCacheKey(tab.id)];
|
||||
if (!entry) return null;
|
||||
if (entry.url !== (tab.url || "")) return null;
|
||||
if (stripHash(entry.url) !== stripHash(tab.url || "")) return null;
|
||||
return entry;
|
||||
} catch { return null; }
|
||||
}
|
||||
|
||||
chrome.tabs.onUpdated.addListener((tabId, changeInfo) => {
|
||||
if (changeInfo.url) chrome.storage.session.remove(tabCacheKey(tabId));
|
||||
if (!changeInfo.url) return;
|
||||
const prev = tabLastUrl.get(tabId);
|
||||
// Hash-only change → keep the cached result; same page, just a fragment jump.
|
||||
if (prev && stripHash(prev) === stripHash(changeInfo.url)) return;
|
||||
chrome.storage.session.remove(tabCacheKey(tabId));
|
||||
});
|
||||
chrome.tabs.onRemoved.addListener((tabId) => {
|
||||
stopBadgeSpinner(tabId);
|
||||
chrome.storage.session.remove(tabCacheKey(tabId));
|
||||
lastAutoCheck.delete(tabId);
|
||||
tabLastUrl.delete(tabId);
|
||||
const t = pendingSpaTimer.get(tabId);
|
||||
if (t) { clearTimeout(t); pendingSpaTimer.delete(tabId); }
|
||||
});
|
||||
@@ -999,6 +1017,7 @@ chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
|
||||
if (changeInfo.status === "complete") {
|
||||
const t = pendingSpaTimer.get(tabId);
|
||||
if (t) { clearTimeout(t); pendingSpaTimer.delete(tabId); }
|
||||
tabLastUrl.set(tabId, tab.url);
|
||||
maybeAutoCheck(tabId, tab, "complete");
|
||||
return;
|
||||
}
|
||||
@@ -1006,6 +1025,11 @@ chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
|
||||
// the page has a chance to update its title/DOM, and so a real reload (which
|
||||
// also emits a url change before complete) doesn't double-fire.
|
||||
if (typeof changeInfo.url === "string") {
|
||||
const prevUrl = tabLastUrl.get(tabId);
|
||||
tabLastUrl.set(tabId, changeInfo.url);
|
||||
// Hash-only change (e.g. `#gallery-2` anchor jump) is purely client-side UI
|
||||
// state. Suppress the SPA scan trigger so anchor navigation doesn't re-fire.
|
||||
if (prevUrl && stripHash(prevUrl) === stripHash(changeInfo.url)) return;
|
||||
const prev = pendingSpaTimer.get(tabId);
|
||||
if (prev) clearTimeout(prev);
|
||||
const handle = setTimeout(() => {
|
||||
|
||||
Reference in New Issue
Block a user