Files
Reddit.openscript/TopCommentSort.os.js
T

62 lines
2.4 KiB
JavaScript

// ==UserScript==
// @name Top Comment Sort
// @version 1.0.0
// @description Opens every Reddit post with its comments sorted by Top, while still letting you pick another sort.
// @match https://www.reddit.com/*
// @run-at document_start
// ==/UserScript==
const POST = /^\/(?:(?:r|u|user)\/[^/]+\/)?comments\/[a-z0-9]+/i;
const KEY = 'os-top-comment-sort';
// Sorted URL for a post page without an explicit sort, otherwise null
const sorted = raw => {
const url = new URL(raw, location.href);
if (url.origin !== location.origin || !POST.test(url.pathname) || url.searchParams.has('sort')) return null;
url.searchParams.set('sort', 'top');
return url.href;
};
// One-shot pass for a path, so a page we already handled (or a sort you picked) is left alone on load
const mark = path => { try { sessionStorage.setItem(KEY, path); } catch {} };
const passed = () => {
try {
const hit = sessionStorage.getItem(KEY) === location.pathname;
sessionStorage.removeItem(KEY);
return hit;
} catch { return false; }
};
// Direct visits: address bar, new tabs, external links
const start = sorted(location.href);
if (!passed() && start) {
mark(location.pathname);
return location.replace(start);
}
// In-page navigation to another post: go to the sorted URL instead
navigation.addEventListener('navigate', e => {
const url = new URL(e.destination.url);
// Same post with a different sort (e.g. the sort dropdown picking Best): respect it
if (url.pathname === location.pathname) {
if (!url.searchParams.has('sort')) mark(url.pathname);
return;
}
const target = e.navigationType === 'push' && e.cancelable && !e.hashChange
&& !e.formData && !e.downloadRequest && sorted(url);
if (!target) return;
e.preventDefault();
e.stopImmediatePropagation();
const nav = navigation.navigate(target, { state: e.destination.getState(), info: e.info });
nav.committed.catch(() => {});
nav.finished.catch(() => {});
});
// Point post links at the sorted URL before they are followed, so the router loads Top directly
const rewrite = e => {
const a = e.composedPath().find(n => n instanceof HTMLAnchorElement && n.href);
const target = a && new URL(a.href).pathname !== location.pathname && sorted(a.href);
if (target) a.href = target;
};
['mousedown', 'click', 'auxclick', 'focusin'].forEach(type => addEventListener(type, rewrite, true));