- Create
extension/directory - Create
extension/src/content/directory - Create
extension/src/popup/directory - Create
extension/assets/directory
- Create
extension/manifest.json - Set manifest_version to 3
- Configure content_scripts to match
https://old.reddit.com/r/*/comments/* - Add
storagepermission - Configure popup action
- Reference icon assets (16, 48, 128)
- Create
extension/assets/icon16.png - Create
extension/assets/icon48.png - Create
extension/assets/icon128.png
- Create
extension/src/popup/popup.html - Add toggle for "Sticky ancestors"
- Add slider/number input for "Pinned rows (N)"
- Add optional checkbox for "Compact sticky rows"
- Create
extension/src/popup/popup.css - Style toggles and controls
- Keep UI clean and minimal
- Create
extension/src/popup/popup.js - Implement
chrome.storage.syncread/write - Set defaults:
stickyAncestorsEnabled: truestickyDepth: 3stickyCompact: true
- Wire UI controls to storage updates
- Create
extension/src/content/selectors.js - Implement
getAllCommentThings()— returns all comment elements - Implement
isCommentThing(el)— checks if element is a comment - Implement
getCommentId(el)— returns unique ID for comment - Implement
getExpandControl(el)— returns clickable expand element - Implement
isCollapsed(el)— checks if comment is collapsed - Implement
getIndentDepth(el)— returns nesting depth - Implement
getParentThing(el)— returns parent comment element
- Create
extension/src/content/util.js - Implement debounce function
- Implement throttle function (if needed)
- Add any shared utility functions
- Create
extension/src/content/main.js - Read settings from
chrome.storage.syncon load - Listen for
chrome.storage.onChangedevents - Initialize/deinitialize feature modules based on settings
- Create
extension/src/content/activeComment.js - Implement IntersectionObserver to track visible comments
- Maintain set of currently visible comments
- Compute "active" comment (smallest positive top distance to viewport top)
- Debounce active comment updates (50-100ms)
- Export
onActiveChange(callback)for notifying changes
- Create
extension/src/content/ancestors.js - Implement
computeAncestors(commentEl)function - Walk backwards in DOM to find parent (depth - 1)
- Repeat until reaching top-level (depth 0)
- Return chain array
[topLevel, ..., currentComment] - Cache depth values in WeakMap for performance
- Create
extension/src/content/stickyUI.js - Create container
div#ta-sticky-container - Style as fixed position at top, full width, high z-index
- Position below Reddit's
#headerto avoid overlap
- Implement
render(chain, N)function - For each comment in
chain.slice(0, N):- Extract and display: author, score, timestamp (optional), short excerpt
- Add "jump" link that scrolls to original comment on click
- Truncate long excerpts with ellipsis
- Keep rendering lightweight (don't clone full comment HTML)
- Measure sticky container height
- Set
document.body.style.paddingTopaccordingly - Update padding when container height changes
- In main.js, register
onActiveChangecallback - On change: compute ancestors, call
stickyUI.render(chain, N) - Handle edge cases:
- Active comment is null → hide container or show post title
- Chain length < N → render only available rows
- Comment is collapsed → still show in sticky using available DOM data
- Add compact rendering option (single-line rows)
- Toggle based on
stickyCompactsetting
- Clicking sticky row scrolls viewport to original comment
- Smooth scroll or instant scroll (user preference)
- Optionally highlight the target comment briefly
- Detect old Reddit header height (
#header) - Set sticky container
topbelow Reddit header
- Watch for newly inserted comments (rare but possible)
- Register new comments with IO observers
- Cache comment depth values (selectors.js: depthCache)
- Cache comment IDs (selectors.js: idCache)
- Cache comment metadata (selectors.js: metaCache)
- Cache parent lookups (ancestors.js: parentCache)
- Cache ancestor chains (ancestors.js: chainCache)
- Only re-render sticky UI when active comment or settings change (currentChainIds comparison)
- Avoid querySelectorAll in scroll handlers (use visibleComments Set)
- Use IO rootMargin instead of manual buffer calculations
- Added performance measurement utilities (Util.perfStart, perfMeasure, perfStats, perfLog)
- Test on large threads (1000+ comments) — manual testing required
- Verify no scroll jank during fast scrolling — manual testing required
- Profile and optimize any bottlenecks — manual testing required
- Enable sticky ancestors with N=3
- Scroll into nested replies → verify pinned chain updates correctly
- Move between sibling threads → verify replacement behavior
- Test with different N values (1, 2, 3, 5)
- Test collapsed parent chains
- Test very shallow threads (< N depth)
- Verify sticky rows don't overlap Reddit header
- Click sticky rows → verify scroll to correct comment
- Test in Chrome
- Test in other Chromium browsers (Edge, Brave, etc.)
- Works on Reddit comment threads (old.reddit.com and www.reddit.com)
- Sticky ancestor header shows correct chain, updates smoothly, supports configurable N
- Toggle state persists across reloads via chrome.storage
- No significant scroll jank on large threads
- UI is clean and doesn't break Reddit's native behavior