Add project housekeeping files and sync manifest version to 0.1.0. Also stages previously untracked chat summaries and score-ratio docs. Co-authored-by: Cursor <cursoragent@cursor.com>
7.2 KiB
Score-per-Comment Ratio Badge
A temperature-coded badge on each post card showing the ratio of score to comments. High ratios (lots of score, few comments) appear hot/red; low ratios appear cold/blue.
Data Extraction
Score Parsing
Old Reddit renders three .score spans inside .midcol: .score.unvoted, .score.likes, .score.dislikes. Only one is visible at a time. When hide_score is true (per-subreddit config or new posts), all three show "•".
Parsing strategy: target .score.unvoted specifically (the neutral/true score). Read its title attribute first (raw integer), fall back to text content. The text fallback must handle abbreviated suffixes (k, m).
| DOM State | .score.unvoted text |
title attr |
Parse result |
|---|---|---|---|
| Normal | "23809" or "23809 points" |
"23809" |
23809 |
| Abbreviated | "23.8k" or "1.2m" |
"23800" (if present) |
23800 / 1200000 |
| Hidden | "•" or "• points" |
"•" or absent |
null |
| Zero net votes | "0" |
"0" |
0 |
| Negative | "-5" |
"-5" |
-5 |
No .score element (promoted/ad) |
n/a | n/a | null |
Text fallback parser: if parseInt fails, try matching /^(-?[\d.]+)\s*([km])/i and multiply by 1000 or 1000000 respectively. If that also fails, return null.
Comment Count Parsing
Parse integer from .flat-list .comments text content. The ratio module does its own parsing (independent of badges.js).
| DOM text | Parse result |
|---|---|
"830 comments" |
830 |
"1 comment" |
1 |
"comment" (old Reddit's 0 form) |
0 |
No .comments element |
null |
Ratio Calculation
Formula: score / comments, displayed to 1 decimal place.
| Score | Comments | Ratio | Badge text | Color |
|---|---|---|---|---|
null (hidden) |
any | — | "—" |
Neutral gray |
| any | null (missing) |
— | "—" |
Neutral gray |
| any | 0 |
Division by zero | "—" |
Neutral gray |
0 |
> 0 |
0.0 |
"0.0 🔥" |
Cold blue |
< 0 |
> 0 |
negative | e.g. "-1.7 🔥" |
Cold blue (clamp at 0) |
420 |
33 |
12.7 |
"12.7 🔥" |
Mapped via HSL |
100000 |
5 |
20000.0 |
"20000.0 🔥" |
Max red |
The 🔥 above represents the Font Awesome fa-fire glyph (solid), not the Unicode emoji. The icon inherits the temperature color.
Temperature Color Scale
HSL hue rotation maps the ratio to a color on the blue → cyan → green → yellow → red spectrum.
- Input: ratio clamped to
[0, 100]for color mapping - Hue formula:
hue = 240 - (clampedRatio / 100) * 240 - Saturation:
80% - Lightness: controlled via CSS, not inline —
45%in light mode,55%when.rt-darkis active
JS sets two CSS custom properties on each badge element:
--rt-ratio-hue: the computed hue (0–240)--rt-ratio-sat:80%(fixed, but exposed as a variable for future tuning)
CSS uses these to derive all colors:
- Text/icon color:
hsl(var(--rt-ratio-hue), var(--rt-ratio-sat), 45%)(light),55%(dark) - Background: same HSL at
10%alpha - Border: same HSL at
25%alpha
This means dark mode toggling requires no DOM walk — the .rt-dark CSS selector changes the lightness value automatically.
| Ratio | Hue | Color |
|---|---|---|
| 0 | 240° | Blue (cold) |
| 12.5 | 210° | Cyan-blue |
| 25 | 180° | Cyan |
| 50 | 120° | Green |
| 75 | 60° | Yellow |
| 100+ | 0° | Red (hot) |
Neutral state ("—" badges): #737373 light, #a3a3a3 dark. These use a separate CSS class (.rt-badge--ratio-neutral) rather than the custom property approach.
Module Architecture
New file: content/tweaks/ratio.js
Exposes window.RedditTweaks.ratioTweak with the standard tweak interface:
apply(settings)— process all existing posts, add ratio badgesprocessNewPosts(settings)— called by mutation observer for infinite scrollupdateSettings(settings)— no-op for now (dark mode handled via CSS), kept for interface consistency
Processing flow per post
- Guard: skip if
data-rt-ratio-processedattribute present - Parse score from
.midcol .score.unvoted(title attr → text fallback with k/m parsing) - Parse comment count from
.flat-list .commentstext - Calculate ratio (or null for edge cases)
- Compute hue from ratio (0–240)
- Create badge:
<span class="rt-badge rt-badge--ratio" style="--rt-ratio-hue:120; --rt-ratio-sat:80%">12.7 <i class="fa-solid fa-fire"></i></span> - Insert into
.reddit-tweaks-badgescontainer if present, otherwise after.taglineinside.entry
New file: content/styles/ratio.css
Depends on .rt-badge base styles from badges.css (always loaded via manifest). Adds:
.rt-badge--ratiostyling: color, background, and border derived from--rt-ratio-hueand--rt-ratio-satcustom properties.rt-dark .rt-badge--ratiooverrides: lightness changes from 45% to 55%.rt-badge--ratio-neutralfor "—" badges: static gray colors, no custom properties
Font Awesome integration
- Bundle FA Free solid subset only (~150KB woff2 + minimal CSS) in
content/fonts/fontawesome/ - Scope all FA CSS selectors under
.rt-badge--ratioto prevent global style pollution (e.g.,.rt-badge--ratio .fa-solidinstead of.fa-solid) - Add scoped FA CSS to
manifest.jsoncontent_scripts CSS array
Integration into main.js
Hard requirement: call order. In both init() and the post observer, badges must process before ratio. This prevents the ratio badge from being orphaned in .entry while .reddit-tweaks-badges is created later.
- Check
settings.scoreRatiotoggle - Call
ratioTweak.apply(settings)during init — afterbadgeTweak.apply() - Call
ratioTweak.processNewPosts(settings)in post observer — afterbadgeTweak.processNewPosts() - Call
ratioTweak.updateSettings(settings)on settings changes (currently a no-op) - Add
scoreRatioto storage change listener for reload triggers
Dependency: the score ratio feature requires badgeLayout or cardLayout to be enabled. The mutation observer only starts when one of those is active. If both are off, ratio badges only appear on the initial page load (no infinite scroll processing). This is an accepted trade-off; the toggle lives under "Card Layout" in the popup to reflect this coupling.
Settings
- New default:
scoreRatio: trueinlib/settings.jsDEFAULTS - Color scale max hardcoded at
100(tunable later)
Popup UI
New toggle in the Card Layout section of popup.html, after "Enable card layout":
<label class="toggle-row">
<span>Score ratio badge</span>
<input type="checkbox" id="scoreRatio">
</label>
Wired into populateControls and saveFromControls in popup.js. No additional configuration UI for the scale max (hardcoded at 100 for now).
Files Changed
| File | Change |
|---|---|
content/tweaks/ratio.js |
New — ratio calculation, badge injection, color math |
content/styles/ratio.css |
New — badge styling, dark mode, neutral state |
content/fonts/fontawesome/ |
New — FA solid subset (woff2 + scoped CSS) |
lib/settings.js |
Add scoreRatio: true to DEFAULTS |
content/main.js |
Wire up ratioTweak lifecycle (after badges, always) |
popup/popup.html |
Add score ratio toggle |
popup/popup.js |
Wire toggle to save/load |
manifest.json |
Add ratio.js, ratio.css, scoped FA CSS to content_scripts |