Skip to content

fix: stop readability breaking on mid-load toggles and hydrating pages - #850

Merged
ankit merged 2 commits into
mainfrom
worktree-fix-readability-followups
Sep 5, 2026
Merged

fix: stop readability breaking on mid-load toggles and hydrating pages#850
ankit merged 2 commits into
mainfrom
worktree-fix-readability-followups

Conversation

@ankit

@ankit ankit commented Sep 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • Fixes toggling readability mid-load: a DOMContentLoaded listener attached after the event already fired (readyState interactive) never ran, leaving the loader stuck forever (repro: The Verge).
  • Fixes a race from that retry: a stale retry could fire after the user toggled readability off and silently re-mount it. Retries now use a generation counter that remove() cancels.
  • Fixes the toolbar badge not updating on toggle — SetReadability now refreshes it like EnableStyle/DisableStyle already do.
  • Splits apply()/remove() out of index.ts into apply.ts and adds unit tests, including a regression test for the toggle-off race.

Test plan

  • yarn lint, yarn jest (138 passing, 8 new), yarn build
  • Verified both original repros (Verge mid-load toggle, Spotify auto-apply) and the toggle-off/badge fixes
  • Swept Wikipedia, Medium, Ars Technica, The Guardian: toggle on/off correct and reverts cleanly
  • github.com/reddit.com still correctly disabled

🤖 Generated with Claude Code

ankit and others added 2 commits September 5, 2026 15:02
Toggling readability while a page was still loading (readyState
'interactive') attached a listener for a DOMContentLoaded event that
had already fired, so it never ran — the loader stayed up forever,
leaving the tab blank. Now only waits for the event when readyState is
still 'loading'; otherwise it proceeds immediately.

Separately, readability silently failed to auto-apply on page load for
client-rendered pages (e.g. Gatsby/JAMstack blogs) whose real content
isn't in the DOM yet at that point, but worked fine when toggled later
by hand. The mount now retries a few times with short delays, and
watches for the mounted reader being wiped out by a later hydration
reconciliation pass (observed on one such site, ~500ms after a
successful mount), re-applying if that happens.

Verified against Wikipedia, Medium, Ars Technica, and The Guardian
(toggle on/off both work and revert cleanly), plus github.com/reddit.com
correctly staying disabled.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…resh badge on toggle

Split readability's apply()/remove() orchestration out of index.ts into
a dedicated apply.ts, and added unit tests for it.

While testing, found the mid-load-hydration retry added a real
regression: if the initial mount failed and scheduled a retry, then the
user turned readability off before that retry fired, the stale retry
would still run afterward and silently re-mount the reader, overriding
the "off" toggle. Retries are now tied to a generation counter that
remove() bumps and cancels, so a superseded retry is a no-op.

Also dropped the MutationObserver-based "clobbering" watch added for
one Gatsby/JAMstack site's post-hydration DOM reconciliation — not
worth the added complexity and harder-to-test surface for a narrow
edge case.

Separately, toggling readability from the popup/editor updated the
stored value but never refreshed the toolbar badge (only EnableStyle/
DisableStyle did). SetReadability's background handler now re-fetches
the tab's styles and calls updateIcon() too.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@ankit
ankit merged commit 11ea42a into main Sep 5, 2026
2 checks passed
@ankit
ankit deleted the worktree-fix-readability-followups branch September 5, 2026 19:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant