Files
userscripts/scripts/old-reddit-mobile.user.js

855 lines
28 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ==UserScript==
// @name Reddit Tweaks (Apollo)
// @version 0.3.0
// @match *://old.reddit.com/*
// @match *://www.reddit.com/*
// @downloadURL https://gist.githubusercontent.com/evanreichard/968eee1cf83da38c81c155fb775cf3c6/raw/old-reddit-mobile.user.js
// @grant GM.addStyle
// @grant GM.registerMenuCommand
// @grant GM.unregisterMenuCommand
// @grant GM.getValue
// @grant GM.setValue
// @grant GM_getValue
// @noframes
// @run-at document-start
// ==/UserScript==
/* ============================================================================
* REDIRECT: www.reddit.com -> old.reddit.com
* ----------------------------------------------------------------------------
* Run before anything else so we don't waste cycles styling the new design.
* The /media path is a special case: Reddit's image viewer wraps the image
* in heavy chrome, so we strip everything down to just the <img> tag.
* ========================================================================== */
if (document.location.host === "www.reddit.com") {
if (document.location.pathname === "/media") {
document.addEventListener("DOMContentLoaded", () => {
const img = document.querySelector("img");
if (img) document.body.innerHTML = img.outerHTML;
});
} else {
window.location.href =
"https://old.reddit.com" +
window.location.pathname +
window.location.search +
window.location.hash;
}
}
/* ============================================================================
* STATE
* ----------------------------------------------------------------------------
* `isEnabled` is read synchronously at script start so we can decide whether
* to inject CSS at document-start (before paint). Toggling the script ALWAYS
* reloads the page — see toggleStyle() for the reasoning.
* ========================================================================== */
let isEnabled = GM_getValue("enabled", true);
/* ============================================================================
* STYLES
* ----------------------------------------------------------------------------
* All visual styling lives here. Uses CSS custom properties for theming so
* dark mode is just a media query override on the :root tokens.
* ========================================================================== */
function applyStyle() {
GM.addStyle(`
/* --------------------------------------------------------------
DESIGN TOKENS
-------------------------------------------------------------- */
:root {
--bg: #ffffff;
--bg-elev: #f7f8fa;
--bg-hover: #eef0f3;
--surface: #ffffff;
--surface-2: #f4f5f7;
--border: #e3e6ea;
--border-soft: #ecedef;
--fg: #1c1c1e;
--fg-2: #3c3c43;
--fg-dim: #6e6e73;
--fg-faint: #b0b3b8;
--accent: #ff4500;
--accent-2: #ff6a33;
--link: #2f6feb;
--visited: #8a8d96;
--upvote: #ff4500;
--downvote: #5b8def;
/* Apollo-style thread depth colors (cycle every 6) */
--depth-1: #4f9cf9; /* blue */
--depth-2: #34c759; /* green */
--depth-3: #ffcc00; /* yellow */
--depth-4: #ff9f0a; /* orange */
--depth-5: #ff453a; /* red */
--depth-6: #bf5af2; /* purple */
--radius-sm: 6px;
--radius: 10px;
--radius-lg: 14px;
--font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display",
"Segoe UI", "Inter", Roboto, system-ui, sans-serif;
--font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
--shadow-sm: 0 1px 2px rgba(0,0,0,0.04);
--shadow: 0 2px 8px rgba(0,0,0,0.06);
--tap: 44px;
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #0e0f12;
--bg-elev: #16181d;
--bg-hover: #1e2128;
--surface: #16181d;
--surface-2: #1c1f25;
--border: #26292f;
--border-soft: #1e2128;
--fg: #f2f2f7;
--fg-2: #d1d1d6;
--fg-dim: #9b9ba1;
--fg-faint: #5a5d63;
--link: #5b8def;
--visited: #6e6f78;
--shadow-sm: 0 1px 2px rgba(0,0,0,0.3);
--shadow: 0 4px 12px rgba(0,0,0,0.4);
}
}
/* --------------------------------------------------------------
GLOBAL RESET / BASE
-------------------------------------------------------------- */
html, body {
background: var(--bg) !important;
color: var(--fg) !important;
font-family: var(--font-sans) !important;
font-size: 15px !important;
line-height: 1.4 !important;
-webkit-font-smoothing: antialiased;
-webkit-text-size-adjust: 100%;
}
a { color: var(--link); text-decoration: none; }
a:visited { color: var(--visited); }
a:hover { color: var(--fg); }
/* Hide all the cruft old.reddit ships with by default */
.side,
.footer-parent,
.rank,
.rank-spacer,
#sr-header-area,
.mobile-web-redirect-bar,
.link.promotedlink,
.infobar.listingsignupbar,
.infobar.welcome,
.listingsignupbar,
.promoted,
[data-promoted="true"],
.res-floatingSideBar,
.bottommenu,
.sr-list,
.sr-bar,
.sr-interest-bar,
.leavemoderator,
.titlebox,
.login-form-side,
.icon-menu .gold-buy,
.reportform,
.panestack-title .res-comments-sortMenu,
.link .flat-list.buttons li.share,
.link .flat-list.buttons .post-sharing-button,
.link .flat-list.buttons .reportbtn {
display: none !important;
}
/* --------------------------------------------------------------
HEADER
-------------------------------------------------------------- */
#header {
background: var(--bg-elev) !important;
border-bottom: 1px solid var(--border) !important;
box-shadow: var(--shadow-sm);
padding: 0 12px !important;
min-height: 48px !important;
height: auto !important;
position: sticky;
top: 0;
z-index: 1000;
backdrop-filter: saturate(180%) blur(12px);
-webkit-backdrop-filter: saturate(180%) blur(12px);
}
#header-bottom-left {
display: flex !important;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
gap: 6px 14px;
padding: 8px 0 !important;
}
#header-img, .pagename a {
color: var(--fg) !important;
font-weight: 700 !important;
font-size: 17px !important;
letter-spacing: -0.01em;
}
.pagename { padding: 0 !important; }
.tabmenu {
width: 100%;
display: flex !important;
gap: 4px;
margin: 0 !important;
overflow-x: auto;
scrollbar-width: none;
}
.tabmenu::-webkit-scrollbar { display: none; }
.tabmenu li { margin: 0 !important; }
.tabmenu li a {
display: inline-block;
padding: 6px 12px !important;
border-radius: 999px;
font-size: 13px !important;
font-weight: 500;
color: var(--fg-dim) !important;
background: transparent !important;
border: 1px solid transparent !important;
transition: background 0.15s ease, color 0.15s ease;
}
.tabmenu li.selected a {
background: var(--accent) !important;
color: #fff !important;
}
.tabmenu li:not(.selected) a:hover {
background: var(--bg-hover) !important;
color: var(--fg) !important;
}
#header-bottom-right {
top: 0;
bottom: unset;
border-radius: 0 0 var(--radius-sm) var(--radius-sm);
background: var(--bg-elev) !important;
color: var(--fg-dim) !important;
font-size: 12px !important;
padding: 6px 10px !important;
border-left: 1px solid var(--border);
border-bottom: 1px solid var(--border);
}
#header-bottom-right a { color: var(--fg-dim) !important; }
/* --------------------------------------------------------------
CONTENT WRAPPER
-------------------------------------------------------------- */
.content[role="main"] {
margin: 0 !important;
padding: 0 !important;
max-width: 100% !important;
background: var(--bg) !important;
color: var(--fg) !important;
}
#siteTable { margin: 0 !important; }
/* --------------------------------------------------------------
POSTS
----------------------------------------------------------------
Flex layout that preserves Reddit's native expando behavior.
Order: thumbnail | entry | (votes hidden) | (wrap) expando
-------------------------------------------------------------- */
.link {
position: relative;
display: flex !important;
flex-wrap: wrap;
align-items: flex-start;
column-gap: 12px;
row-gap: 4px;
padding: 12px 14px !important;
margin: 0 !important;
background: var(--surface) !important;
color: var(--fg) !important;
border: 0 !important;
border-bottom: 1px solid var(--border-soft) !important;
transition: background 0.12s ease;
}
.link:active { background: var(--bg-hover) !important; }
.link.last-clicked {
background: var(--bg-elev) !important;
border-bottom: 1px solid var(--border-soft) !important;
}
.link > .thumbnail { order: 1; flex: 0 0 auto; }
.link > .entry { order: 2; flex: 1 1 0; min-width: 0; }
.link > .midcol { order: 3; flex: 0 0 auto; }
.link > .child,
.link > .clearleft { display: none !important; }
/* Hide post-level vote arrows and native expando button (we tap thumbnail instead) */
.link > .midcol { display: none !important; }
.link .expando-button { display: none !important; }
/* Thumbnail container — shared by real and synthetic thumbs */
.link > .thumbnail {
width: 64px !important;
height: 64px !important;
margin: 0 !important;
border-radius: var(--radius);
overflow: hidden;
background: var(--bg-elev);
border: 1px solid var(--border-soft);
display: flex !important;
align-items: center;
justify-content: center;
cursor: pointer;
}
.link > .thumbnail img {
width: 100% !important;
height: 100% !important;
object-fit: cover !important;
display: block;
}
/* Placeholder labels when there's no real image */
.link > .thumbnail.self::after,
.link > .thumbnail.default::after,
.link > .thumbnail.spoiler::after,
.link > .thumbnail.nsfw::after {
font-size: 10px;
font-weight: 700;
letter-spacing: 0.05em;
color: var(--fg-dim);
}
.link > .thumbnail.self::after { content: "TEXT"; }
.link > .thumbnail.default::after { content: "LINK"; }
.link > .thumbnail.spoiler::after { content: "⚠"; font-size: 18px; }
.link.over18 > .thumbnail::after { content: "NSFW"; color: #ff453a; }
/* Entry / title / meta */
.link .entry { margin: 0 !important; color: var(--fg) !important; }
.link .top-matter { padding: 0 !important; margin: 0 !important; }
.link .title {
margin: 0 0 4px 0 !important;
padding: 0 !important;
font-size: 15px !important;
line-height: 1.3 !important;
font-weight: 500;
letter-spacing: -0.01em;
}
.link .title a.title { color: var(--fg) !important; }
.link.visited .title a.title,
.link .title a.title:visited { color: var(--fg-dim) !important; }
.link .title .domain {
display: inline-block;
font-size: 11px !important;
color: var(--fg-dim) !important;
font-weight: 400;
margin-left: 4px;
vertical-align: middle;
}
.link .title .domain a { color: var(--fg-dim) !important; }
.link .linkflairlabel {
display: inline-flex;
align-items: center;
gap: 3px;
font-size: 10.5px !important;
font-weight: 600;
padding: 2px 7px !important;
border-radius: 999px;
margin-right: 6px;
vertical-align: middle;
line-height: 1.4;
border: 0 !important;
}
.link .flairemoji { width: 12px !important; height: 12px !important; }
.link .tagline {
font-size: 12px !important;
color: var(--fg-dim) !important;
margin: 0 !important;
line-height: 1.3 !important;
}
.link .tagline a,
.link .tagline time { color: var(--fg-dim) !important; }
.link .tagline .author { color: var(--fg-2) !important; font-weight: 500; }
.link .flat-list.buttons {
display: flex;
gap: 12px;
margin: 4px 0 0 0 !important;
padding: 0 !important;
font-size: 12px !important;
list-style: none;
}
.link .flat-list.buttons li { display: inline-block; margin: 0; padding: 0; }
.link .flat-list.buttons a { color: var(--fg-dim) !important; font-weight: 500; }
.link .flat-list.buttons .comments {
color: var(--accent) !important;
font-weight: 600;
}
/* --------------------------------------------------------------
EXPANDO (full-width row beneath the post)
-------------------------------------------------------------- */
.link > .expando {
order: 4;
flex: 0 0 100%;
width: 100% !important;
max-width: 100% !important;
margin: 8px 0 0 0 !important;
padding: 0 !important;
background: transparent !important;
border: 0 !important;
color: var(--fg) !important;
box-sizing: border-box;
}
.link > .expando .media-preview,
.link > .expando .media-preview-content,
.link > .expando .res-expando-box,
.link > .expando .res-expando-box div {
max-width: 100% !important;
width: 100% !important;
}
.link .expando img,
.link .expando video,
.link .expando iframe,
.link .expando .preview,
.link .expando .media-preview-content > * {
max-width: 100% !important;
height: auto !important;
border-radius: var(--radius);
display: block;
}
/* Self-text body */
.link .expando .usertext-body,
.link .usertext-body,
.commentarea .link .usertext-body {
background: var(--surface-2) !important;
color: var(--fg) !important;
border: 1px solid var(--border-soft) !important;
border-radius: var(--radius);
padding: 10px 14px !important;
margin: 0 !important;
}
.link .expando .md,
.link .usertext-body .md {
background: transparent !important;
color: var(--fg) !important;
max-width: unset !important;
font-size: 14px !important;
line-height: 1.55 !important;
}
.link .expando .md p,
.link .expando .md li,
.link .expando .md h1,
.link .expando .md h2,
.link .expando .md h3,
.link .expando .md blockquote {
color: var(--fg) !important;
}
/* --------------------------------------------------------------
COMMENTS — bubble-in-bubble with depth-colored left border
-------------------------------------------------------------- */
.commentarea {
background: var(--bg) !important;
color: var(--fg) !important;
padding: 8px 10px !important;
margin: 0 !important;
}
.commentarea > .menuarea {
background: transparent !important;
border: 0 !important;
padding: 8px 4px !important;
margin: 0 0 4px 0 !important;
font-size: 12px;
color: var(--fg-dim) !important;
}
.comment {
background: var(--surface) !important;
color: var(--fg) !important;
border: 1px solid var(--border-soft) !important;
border-left: 3px solid var(--depth-1) !important;
border-radius: var(--radius);
padding: 10px 12px !important;
margin: 6px 0 !important;
box-shadow: var(--shadow-sm);
}
.comment .child,
.comment .showreplies {
border-left: 0 !important;
margin: 6px 0 0 6px !important;
padding: 0 !important;
}
/* Cycle border colors by nesting depth */
.comment .comment { border-left-color: var(--depth-2) !important; }
.comment .comment .comment { border-left-color: var(--depth-3) !important; }
.comment .comment .comment .comment { border-left-color: var(--depth-4) !important; }
.comment .comment .comment .comment .comment { border-left-color: var(--depth-5) !important; }
.comment .comment .comment .comment .comment .comment { border-left-color: var(--depth-6) !important; }
.comment .comment .comment .comment .comment .comment .comment { border-left-color: var(--depth-1) !important; }
.comment .comment .comment .comment .comment .comment .comment .comment { border-left-color: var(--depth-2) !important; }
.comment .comment .comment .comment .comment .comment .comment .comment .comment { border-left-color: var(--depth-3) !important; }
/* Alternate bg shades to emphasize nesting */
.comment .comment { background: var(--surface-2) !important; }
.comment .comment .comment { background: var(--surface) !important; }
.comment .entry { padding: 0 !important; }
.comment .tagline {
font-size: 12px !important;
color: var(--fg-dim) !important;
margin-bottom: 4px;
}
.comment .tagline .author { color: var(--fg) !important; font-weight: 600; }
.comment .tagline .submitter { color: var(--link) !important; font-weight: 600; }
.comment .tagline .score { color: var(--fg-dim) !important; font-weight: 500; }
.comment .usertext-body,
.comment .usertext-body .md,
.comment .md {
font-size: 14px !important;
line-height: 1.5 !important;
color: var(--fg) !important;
background: transparent !important;
}
.comment .md p { margin: 4px 0 !important; color: var(--fg) !important; }
.comment .md a { color: var(--link) !important; }
.comment .md blockquote {
border-left: 3px solid var(--border);
padding-left: 10px;
color: var(--fg-2) !important;
margin: 6px 0;
}
.comment .md code {
background: var(--bg-elev) !important;
color: var(--fg) !important;
border-radius: 4px;
padding: 1px 5px;
font-family: var(--font-mono);
font-size: 12.5px;
}
.comment .md pre {
background: var(--bg-elev) !important;
color: var(--fg) !important;
padding: 8px 10px;
border-radius: var(--radius-sm);
overflow-x: auto;
}
.comment .midcol {
width: 16px !important;
margin-right: 4px !important;
}
.comment .arrow {
width: 18px !important;
height: 18px !important;
background-size: 14px !important;
border-radius: 4px;
}
.comment .arrow:hover { background-color: var(--bg-hover); }
.comment .flat-list.buttons {
font-size: 12px !important;
margin-top: 4px !important;
}
.comment .flat-list.buttons a { color: var(--fg-dim) !important; font-weight: 500; }
.comment .flat-list.buttons .reply-button a { color: var(--link) !important; }
.comment .expand {
color: var(--fg-dim) !important;
font-weight: 600;
padding: 0 4px;
}
.comment.collapsed {
opacity: 0.7;
padding: 6px 12px !important;
}
/* "load more" buttons */
.morechildren a, .morecomments a {
display: inline-block;
padding: 6px 12px;
border-radius: 999px;
background: var(--bg-elev) !important;
color: var(--link) !important;
font-weight: 600;
font-size: 13px;
border: 1px solid var(--border) !important;
}
/* --------------------------------------------------------------
PAGINATION
-------------------------------------------------------------- */
.nextprev {
display: flex;
justify-content: space-between;
align-items: stretch;
gap: 10px;
padding: 16px 14px 28px;
margin: 0;
}
.nextprev .separator { display: none; }
.nextprev a {
flex: 1 1 0;
min-height: var(--tap);
display: flex;
align-items: center;
justify-content: center;
padding: 12px 16px;
border-radius: var(--radius);
font-weight: 600;
font-size: 15px;
text-decoration: none;
background: var(--bg-elev) !important;
color: var(--fg) !important;
border: 1px solid var(--border);
transition: transform 0.06s ease, background 0.15s ease;
}
.nextprev a:hover { background: var(--bg-hover) !important; }
.nextprev a:active { transform: scale(0.98); }
.nextprev a[rel*="next"] {
background: var(--accent) !important;
color: #fff !important;
border-color: transparent;
}
.nextprev a[rel*="next"]:hover { background: var(--accent-2) !important; }
/* --------------------------------------------------------------
FORMS / MENUS / MISC
-------------------------------------------------------------- */
input[type=text],
input[type=password],
input[type=email],
textarea {
background: var(--bg-elev) !important;
color: var(--fg) !important;
border: 1px solid var(--border) !important;
border-radius: var(--radius-sm) !important;
padding: 8px 10px !important;
font-family: var(--font-sans) !important;
font-size: 14px !important;
}
.btn, button, .morelink a {
background: var(--bg-elev) !important;
color: var(--fg) !important;
border: 1px solid var(--border) !important;
border-radius: var(--radius-sm) !important;
padding: 6px 12px !important;
font-weight: 600;
font-family: var(--font-sans) !important;
}
.menuarea, .panestack-title {
background: transparent !important;
border: 0 !important;
color: var(--fg-dim) !important;
padding: 8px 12px !important;
}
.dropdown, .drop-choices {
background: var(--surface) !important;
color: var(--fg) !important;
border: 1px solid var(--border) !important;
border-radius: var(--radius-sm) !important;
box-shadow: var(--shadow);
}
table, th, td {
background: var(--surface) !important;
color: var(--fg) !important;
border-color: var(--border) !important;
}
pre, code {
background: var(--bg-elev) !important;
color: var(--fg) !important;
font-family: var(--font-mono) !important;
}
/* Dim Reddit's default vote arrows in dark mode (they're black PNGs) */
@media (prefers-color-scheme: dark) {
.arrow:not(.upmod):not(.downmod) { filter: brightness(0.85) invert(0.9); }
}
a, button { touch-action: manipulation; }
body > .content .link .midcol { width: auto !important; }
body > .content .link .rank, .rank-spacer { width: 0 !important; }
`);
// Mobile viewport — Reddit's default doesn't include viewport-fit=cover,
// which we want for safe-area handling on notched devices.
if (document.head) {
const meta = document.createElement("meta");
meta.setAttribute("name", "viewport");
meta.setAttribute(
"content",
"width=device-width, initial-scale=1, viewport-fit=cover",
);
document.head.appendChild(meta);
}
// Nuke subreddit-specific stylesheet ASAP so it can't fight ours
document.head?.querySelector("[ref=applied_subreddit_stylesheet]")?.remove();
}
/* ============================================================================
* DOM TWEAKS
* ----------------------------------------------------------------------------
* Things CSS alone can't do: rewriting nodes, injecting placeholders,
* relocating elements within the post layout.
* ========================================================================== */
function applyDOMTweaks() {
// Belt-and-suspenders subreddit stylesheet removal (in case it loaded after us)
document.querySelector('link[title="applied_subreddit_stylesheet"]')?.remove();
// Replace the subreddit logo/banner anchor with a plain "reddit" home link
const headerAnchor = document.querySelector("#header-bottom-left a");
if (headerAnchor) {
headerAnchor.outerHTML =
`<a href="/" id="header-img" class="default-header" title="">reddit</a>`;
}
// Process every post on the page
document.querySelectorAll(".link").forEach(processLink);
// Pagination polish — shorten "view more" wording and add arrows
const nextprev = document.querySelector(".nextprev");
if (nextprev) {
// The first text node is often "view more:" — drop it
const first = nextprev.childNodes[0];
if (first && first.textContent.trim().toLowerCase().startsWith("view more")) {
first.remove();
}
nextprev.querySelectorAll("a").forEach((a) => {
const rel = (a.getAttribute("rel") || "").toLowerCase();
if (rel.includes("next")) a.textContent = "Next ";
else if (rel.includes("prev")) a.textContent = " Prev";
});
// Center the lone button if there's only one direction available
if (nextprev.querySelectorAll("a").length === 1) {
nextprev.style.justifyContent = "center";
nextprev.querySelector("a").style.flex = "0 1 280px";
}
}
}
/**
* Per-post tweaks:
* 1. Move .expando out of .entry so it can become a full-width flex row
* (flex order: thumbnail | entry | expando-on-new-line).
* 2. Inject a synthetic .thumbnail <div> when the subreddit suppresses
* thumbnails server-side (e.g. r/cars). This guarantees every post
* has a tappable thumb area showing "TEXT", "LINK", "NSFW", etc.
*/
function processLink(link) {
// --- 1. Promote .expando to be a direct child of .link ---
const expando = link.querySelector(":scope > .entry > .expando");
if (expando) link.appendChild(expando);
// --- 2. Inject synthetic thumbnail if missing ---
if (!link.querySelector(":scope > .thumbnail")) {
const thumb = document.createElement("div");
// Pick the right placeholder class so CSS ::after shows the right label
if (link.classList.contains("over18")) {
thumb.className = "thumbnail nsfw";
} else if (link.classList.contains("spoiler")) {
thumb.className = "thumbnail spoiler";
} else if (link.classList.contains("self")) {
thumb.className = "thumbnail self";
} else {
thumb.className = "thumbnail default";
}
link.prepend(thumb);
}
}
/* ============================================================================
* INTERACTION HANDLERS
* ----------------------------------------------------------------------------
* Delegated click handlers — attached once at script start, gated on
* `isEnabled` so they no-op when the user disables the script live.
* ========================================================================== */
// Tap a comment body to collapse/expand it (Apollo-style)
document.addEventListener("click", (evt) => {
if (!isEnabled) return;
// Ignore clicks on interactive descendants
if (evt.target.closest("a")) return;
if (evt.target.classList.contains("expand")) return;
if (evt.target.closest(".flat-list.buttons")) return;
if (evt.target.closest(".usertext-edit")) return;
if (evt.target.closest(".midcol")) return;
const comment = evt.target.closest(".comment");
if (!comment) return;
const expander = comment.querySelector(":scope > .entry .expand");
if (!expander) return;
expander.click();
});
// Tap a thumbnail to toggle the post's expando.
// On synthetic thumbnails (link posts with no expando) this is a no-op.
document.addEventListener("click", (evt) => {
if (!isEnabled) return;
let thumb;
if (evt.target.classList?.contains("thumbnail")) {
thumb = evt.target;
} else if (evt.target.parentElement?.classList?.contains("thumbnail")) {
thumb = evt.target.parentElement;
}
if (!thumb) return;
const link = thumb.closest(".link");
if (!link) return;
const btn = link.querySelector(".expando-button");
evt.preventDefault();
evt.stopPropagation();
if (!btn) return; // synthetic thumb, nothing to expand
btn.click();
});
/* ============================================================================
* MENU / TOGGLE
* ----------------------------------------------------------------------------
* Toggling always reloads the page. Why:
* - GM.addStyle injects a <style> tag that can't be cleanly removed without
* tracking references and tearing them down.
* - DOM tweaks (moved expandos, injected thumbnails, replaced header anchor)
* can't be reversed without remembering the original state.
* - A reload gives a clean, predictable state for both directions.
* ========================================================================== */
async function toggleStyle() {
const currentlyEnabled = await GM.getValue("enabled", true);
await GM.setValue("enabled", !currentlyEnabled);
window.location.reload();
}
function registerMenu() {
const label = isEnabled ? "Style - Disable" : "Style - Enable";
GM.registerMenuCommand(label, toggleStyle);
}
/* ============================================================================
* BOOT
* ========================================================================== */
if (isEnabled) {
applyStyle(); // inject CSS at document-start
window.addEventListener("load", applyDOMTweaks); // DOM tweaks once page is ready
}
registerMenu();