855 lines
28 KiB
JavaScript
855 lines
28 KiB
JavaScript
// ==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();
|