fix: subreddit badge fill, tagline 'to' cleanup, and comments li spacing
- Default subreddit badge background from transparent to opaque fill (light: #fde8e0, dark: #3d2518) so page highlights don't bleed through - Remove lingering "to" text node from tagline when subreddit is hidden - Hide the <li> wrapping the comments link (not just the <a>) to eliminate leftover whitespace in the flat-list - Simplify popup: subreddit bg fields are now color pickers (no longer need transparent text-input workaround) Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
40
chat-summaries/2026-08-26_14-07-summary.md
Normal file
40
chat-summaries/2026-08-26_14-07-summary.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Firefox Reddit Tweaks Extension — Full Build
|
||||||
|
|
||||||
|
**Date:** 2026-08-26
|
||||||
|
|
||||||
|
## Task
|
||||||
|
|
||||||
|
Design and implement a Firefox extension that reskins old Reddit post listings by moving subreddit names and comment counts into styled badge elements above each post title.
|
||||||
|
|
||||||
|
## Process
|
||||||
|
|
||||||
|
1. **Brainstorming** — Explored requirements via mockup analysis and clarifying questions (old Reddit only, all pages, user-configurable colors with per-subreddit overrides, light/dark mode)
|
||||||
|
2. **Design spec** — Written, self-reviewed, committed (`docs/superpowers/specs/2026-08-26-reddit-badge-tweaks-design.md`)
|
||||||
|
3. **Adversarial review** — Found and resolved 9 gaps (div.thing selector, shared module loading, FOUC, teardown logic, dark mode timing, observer target, comment text parsing, permissions, storage quotas)
|
||||||
|
4. **Implementation plan** — 4 tasks, committed (`docs/superpowers/plans/2026-08-26-reddit-badge-tweaks.md`)
|
||||||
|
5. **Subagent-driven execution** — Each task dispatched to implementer, then reviewed:
|
||||||
|
- Task 1: Manifest + settings module + icons
|
||||||
|
- Task 2: Badge CSS with FOUC prevention
|
||||||
|
- Task 3: Badge DOM manipulation with MutationObservers
|
||||||
|
- Task 4: Settings popup UI
|
||||||
|
6. **Final review** — Found 1 Critical (disabled-state hides UI), 2 Important (shallow merge, fire-and-forget saves). All fixed.
|
||||||
|
|
||||||
|
## Files Created
|
||||||
|
|
||||||
|
- `manifest.json` — Extension manifest (MV2)
|
||||||
|
- `lib/settings.js` — Settings read/write module
|
||||||
|
- `content/styles/badges.css` — Badge styling + FOUC prevention
|
||||||
|
- `content/tweaks/badges.js` — DOM manipulation + observers
|
||||||
|
- `content/main.js` — Entry point + storage listener
|
||||||
|
- `popup/popup.html` — Settings UI
|
||||||
|
- `popup/popup.css` — Settings styling
|
||||||
|
- `popup/popup.js` — Settings logic
|
||||||
|
- `icons/icon-48.png`, `icons/icon-96.png` — Placeholder icons
|
||||||
|
|
||||||
|
## Follow-up Items
|
||||||
|
|
||||||
|
- Manual QA in Firefox via `about:debugging` (test checklist in spec, items 1-15)
|
||||||
|
- Replace placeholder icons with proper design
|
||||||
|
- Optional: extract subreddit name helper for DRY
|
||||||
|
- Optional: add error handling to `loadSettings()` / `init()`
|
||||||
|
- Optional: support transparent backgrounds in per-subreddit overrides
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/* --- FOUC prevention: hide original elements immediately --- */
|
/* --- FOUC prevention: hide original elements immediately --- */
|
||||||
html.rt-enabled .thing.link .tagline .subreddit,
|
html.rt-enabled .thing.link .tagline .subreddit,
|
||||||
html.rt-enabled .thing.link .flat-list .comments {
|
html.rt-enabled .thing.link .flat-list li:has(> .comments) {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ html.rt-enabled .thing.link .flat-list .comments {
|
|||||||
|
|
||||||
/* --- Light mode (default) --- */
|
/* --- Light mode (default) --- */
|
||||||
.rt-badge--subreddit {
|
.rt-badge--subreddit {
|
||||||
background: var(--rt-sub-bg, transparent);
|
background: var(--rt-sub-bg, #fde8e0);
|
||||||
border-color: var(--rt-sub-border, #c84a20);
|
border-color: var(--rt-sub-border, #c84a20);
|
||||||
color: var(--rt-sub-text, #c84a20);
|
color: var(--rt-sub-text, #c84a20);
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ html.rt-enabled .thing.link .flat-list .comments {
|
|||||||
|
|
||||||
/* --- Dark mode --- */
|
/* --- Dark mode --- */
|
||||||
.rt-dark .rt-badge--subreddit {
|
.rt-dark .rt-badge--subreddit {
|
||||||
background: var(--rt-sub-bg, transparent);
|
background: var(--rt-sub-bg, #3d2518);
|
||||||
border-color: var(--rt-sub-border, #ff6b3d);
|
border-color: var(--rt-sub-border, #ff6b3d);
|
||||||
color: var(--rt-sub-text, #ff6b3d);
|
color: var(--rt-sub-text, #ff6b3d);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,11 @@
|
|||||||
badge.textContent = subLink.textContent.trim();
|
badge.textContent = subLink.textContent.trim();
|
||||||
subredditName = subLink.textContent.trim().replace(/^r\//, "");
|
subredditName = subLink.textContent.trim().replace(/^r\//, "");
|
||||||
container.appendChild(badge);
|
container.appendChild(badge);
|
||||||
|
|
||||||
|
const prevNode = subLink.previousSibling;
|
||||||
|
if (prevNode && prevNode.nodeType === Node.TEXT_NODE && /\bto\s*$/.test(prevNode.textContent)) {
|
||||||
|
prevNode.textContent = prevNode.textContent.replace(/\s*to\s*$/, " ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const commentsLink = post.querySelector(".flat-list .comments");
|
const commentsLink = post.querySelector(".flat-list .comments");
|
||||||
|
|||||||
@@ -4,13 +4,13 @@
|
|||||||
const DEFAULTS = {
|
const DEFAULTS = {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
darkMode: "auto",
|
darkMode: "auto",
|
||||||
"light.subredditBgColor": "transparent",
|
"light.subredditBgColor": "#fde8e0",
|
||||||
"light.subredditBorderColor": "#c84a20",
|
"light.subredditBorderColor": "#c84a20",
|
||||||
"light.subredditTextColor": "#c84a20",
|
"light.subredditTextColor": "#c84a20",
|
||||||
"light.commentsBgColor": "#e0e0e0",
|
"light.commentsBgColor": "#e0e0e0",
|
||||||
"light.commentsBorderColor": "#4a4a4a",
|
"light.commentsBorderColor": "#4a4a4a",
|
||||||
"light.commentsTextColor": "#4a4a4a",
|
"light.commentsTextColor": "#4a4a4a",
|
||||||
"dark.subredditBgColor": "transparent",
|
"dark.subredditBgColor": "#3d2518",
|
||||||
"dark.subredditBorderColor": "#ff6b3d",
|
"dark.subredditBorderColor": "#ff6b3d",
|
||||||
"dark.subredditTextColor": "#ff6b3d",
|
"dark.subredditTextColor": "#ff6b3d",
|
||||||
"dark.commentsBgColor": "#3a3a3a",
|
"dark.commentsBgColor": "#3a3a3a",
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
<h2>Light Mode Colors</h2>
|
<h2>Light Mode Colors</h2>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Subreddit Badge</legend>
|
<legend>Subreddit Badge</legend>
|
||||||
<label>Background <input type="text" id="light.subredditBgColor"></label>
|
<label>Background <input type="color" id="light.subredditBgColor"></label>
|
||||||
<label>Border <input type="color" id="light.subredditBorderColor"></label>
|
<label>Border <input type="color" id="light.subredditBorderColor"></label>
|
||||||
<label>Text <input type="color" id="light.subredditTextColor"></label>
|
<label>Text <input type="color" id="light.subredditTextColor"></label>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
<h2>Dark Mode Colors</h2>
|
<h2>Dark Mode Colors</h2>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Subreddit Badge</legend>
|
<legend>Subreddit Badge</legend>
|
||||||
<label>Background <input type="text" id="dark.subredditBgColor"></label>
|
<label>Background <input type="color" id="dark.subredditBgColor"></label>
|
||||||
<label>Border <input type="color" id="dark.subredditBorderColor"></label>
|
<label>Border <input type="color" id="dark.subredditBorderColor"></label>
|
||||||
<label>Text <input type="color" id="dark.subredditTextColor"></label>
|
<label>Text <input type="color" id="dark.subredditTextColor"></label>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|||||||
@@ -2,11 +2,13 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const COLOR_KEYS = [
|
const COLOR_KEYS = [
|
||||||
|
"light.subredditBgColor",
|
||||||
"light.subredditBorderColor",
|
"light.subredditBorderColor",
|
||||||
"light.subredditTextColor",
|
"light.subredditTextColor",
|
||||||
"light.commentsBgColor",
|
"light.commentsBgColor",
|
||||||
"light.commentsBorderColor",
|
"light.commentsBorderColor",
|
||||||
"light.commentsTextColor",
|
"light.commentsTextColor",
|
||||||
|
"dark.subredditBgColor",
|
||||||
"dark.subredditBorderColor",
|
"dark.subredditBorderColor",
|
||||||
"dark.subredditTextColor",
|
"dark.subredditTextColor",
|
||||||
"dark.commentsBgColor",
|
"dark.commentsBgColor",
|
||||||
@@ -14,13 +16,8 @@
|
|||||||
"dark.commentsTextColor",
|
"dark.commentsTextColor",
|
||||||
];
|
];
|
||||||
|
|
||||||
const BG_KEYS = [
|
|
||||||
"light.subredditBgColor",
|
|
||||||
"dark.subredditBgColor",
|
|
||||||
];
|
|
||||||
|
|
||||||
function colorToHex(val) {
|
function colorToHex(val) {
|
||||||
if (!val || val === "transparent") return "#ffffff";
|
if (!val) return "#ffffff";
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,14 +30,6 @@
|
|||||||
if (el) el.value = colorToHex(settings[key]);
|
if (el) el.value = colorToHex(settings[key]);
|
||||||
});
|
});
|
||||||
|
|
||||||
BG_KEYS.forEach(function (key) {
|
|
||||||
const el = document.getElementById(key);
|
|
||||||
if (el) {
|
|
||||||
el.value = settings[key] === "transparent" ? "" : settings[key];
|
|
||||||
el.placeholder = "transparent";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
renderSubredditOverrides(settings.subredditColors || {});
|
renderSubredditOverrides(settings.subredditColors || {});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,13 +116,6 @@
|
|||||||
if (el) settings[key] = el.value;
|
if (el) settings[key] = el.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
BG_KEYS.forEach(function (key) {
|
|
||||||
const el = document.getElementById(key);
|
|
||||||
if (el) {
|
|
||||||
settings[key] = el.value.trim() || "transparent";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await window.RedditTweaks.saveSettings(settings);
|
await window.RedditTweaks.saveSettings(settings);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -153,11 +135,6 @@
|
|||||||
if (el) el.addEventListener("input", saveFromControls);
|
if (el) el.addEventListener("input", saveFromControls);
|
||||||
});
|
});
|
||||||
|
|
||||||
BG_KEYS.forEach(function (key) {
|
|
||||||
const el = document.getElementById(key);
|
|
||||||
if (el) el.addEventListener("input", saveFromControls);
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById("addSubreddit").addEventListener("click", function () {
|
document.getElementById("addSubreddit").addEventListener("click", function () {
|
||||||
addSubredditEntry("", {});
|
addSubredditEntry("", {});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user