Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

[Feature Request] Keep dynamic fixes active after dark theme detector stand-down ("theme off, fixes on")

未关闭
#15,992 4 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
5/5
预计耗时
一周以上
新手友好度
42/100
Issue 类型
功能
描述清晰度
基本清楚
活跃度
活跃
技术栈
typescript
领域
frontend

调研方向

从 src/inject/detector.ts、detector-hints.config 格式以及 src/inject/index.ts 中的 ADD_DYNAMIC_THEME handler 开始。跟踪当前 dark 检测的停用流程,并确定 opt-in KEEP FIXES 指令如何在不使用主题的 UA-stylesheet 覆盖的情况下保留 URL 匹配的 fixes。完成的标准是:该指令得到明确支持,现有网站保持当前行为,并且 detector 生命周期有测试覆盖。

由索引模型根据 Issue 内容生成。

描述

enhancement
Prerequisites
Is this feature request related to a problem?

Yes

Feature Request Description

Problem

Dark Reader's dark theme detector is strictly binary: when it concludes a site ships its own dark theme, it performs a full stand-down (removeDynamicTheme() + CLEAN_UP), discarding everything — including URL-matched dynamic fixes. That verdict is architecturally correct (a native dark theme should not be double-transformed), but it leaves a real class of sites unpatchable: natively dark sites whose dark theme itself has a first-paint / hydration bug. This pattern is common in SPAs with CSS-in-JS theme contexts that initialize after hydration. On such sites:

  • No dynamic fix can help, because fixes are torn down together with the theme at the moment of stand-down (src/inject/index.ts, ADD_DYNAMIC_THEME handler). The fix database is structurally empty exactly where it is needed.
  • The NO DARK THEME hint forces Dark Reader to keep transforming — rejected in #15959 as an anti-pattern, and rightly so.
  • The TARGET/MATCH hint merged in #15959 cannot express it either (see below).

So today there is no mechanism that can say: "trust this site's dark theme, but keep the documented fix entries to patch its broken first paint."

Concrete example: pixiv.net

  • An inline head script sets <html data-theme="dark"> before first paint — correct.
  • But the React theme context initially renders styled-components with light values and only syncs to dark after hydration. Captured with an insertRule recorder: light rule at ~1195 ms, dark variant of the same component at ~1352 ms.
  • Out of the box (detectDarkTheme defaults to true), both the generic path (runCheck() checks document.documentElement.dataset.theme === 'dark' in src/inject/detector.ts) and the merged hint detect the site as dark and Dark Reader stands down entirely — leaving the white window exposed on every warm-start load.
  • The merged TARGET html + MATCH [data-theme="dark"] hint is behaviorally a no-op here: it matches the same attribute on the same element the generic path already checks. Its only effect is timing — detectUsingHint() can fire before canCheckForStyle() would let runCheck() run, so the stand-down happens earlier and covers less of the race window. (Repro is timing-dependent: on MV3 cold start, service-worker wake-up can push the inject → detect cycle past the hydration window, which is likely why the flash did not reproduce during review.)

Proposed solution

A new opt-in directive in detector-hints.config — KEEP FIXES, usable alongside TARGET/MATCH:

  • On dark detection for a hinted site, the content script drops the generated theme but keeps the URL's dynamic fix entries applied ("theme off, fixes on"), instead of the current removeDynamicTheme() + DARK_THEME_DETECTED → CLEAN_UP sequence.
  • A fixes-only rebuild should skip the UA-stylesheet overrides an active theme injects (e.g. html { background-color } / color-scheme), since the native theme already handles those.
  • Everything remains opt-in: sites without the directive behave exactly as today.

This directly resolves the anti-pattern concern from #15959 — Dark Reader no longer transforms native dark stylesheets, it only applies explicitly documented per-site patches — and it gives the fix database an actual role on native-dark sites. Without it, writing a per-site fix for pixiv is pointless, because no such fix can survive the stand-down.

Design questions (cc @alexanderby)

  1. Is a hint directive the right shape, or would you prefer fixes to live in a separate stylesheet channel from the start, so stand-down removes only the theme channel?
  2. Runtime theme flips (e.g. the user switches the site to light mode and MATCH stops matching): should detection re-run, and should the kept fixes be re-evaluated or removed?
  3. After DARK_THEME_DETECTED, the background currently treats the tab like a dark-listed site (isURLEnabled()). Should the fixes-only state persist across navigations in the same way?
  4. Fix-rot: the 2020 pixiv entry targeted styled-components hash classes that no longer exist. Is dynamic-theme-fixes still the right home for such patches, or should they belong to static themes / a new category?
Screenshots
  • insertRule recording of the pixiv.net hydration race: light rule inserted at ~1195 ms, dark variant of the same component at ~1352 ms (attached).
  • Console trace of the warm-start sequence: DR theme injected → detector matches html[data-theme="dark"] → theme removed → white components visible until hydration completes.
  • Control: same load with the detector disabled (detectDarkTheme off) — no flash, Dark Reader's near-identity transform covers the window.
Additional Context
  • Background discussion: #15959 (pixiv.net detector hint; includes the hydration-race analysis and the review conversation with @Myshor, who suggested opening this issue: "Proposing a new engine behavior or config directive ... affects core Dark Reader architecture beyond just pixiv.net").

Related issues (searched before filing; no duplicate of this proposal found):

  • Same code path, state lifecycle: #15509 (dark-detected / NO DARK THEME state not re-evaluated during in-site navigation), #15913 + #15990 (cold-start race leaving DETECTOR_HINTS_INDEX undefined — also why detector-related flashes reproduce inconsistently).

  • Hint DSL extensions currently in flight: #15929, #15930 (MATCH SYSTEM DARK/LIGHT) — this proposal adds a post-verdict directive rather than another matching mode.

  • Verdict-accuracy requests, different problem: #1327, #10792, #13160, #12238, #15033 — these concern whether a site is dark; this proposal concerns what Dark Reader retains after a correct verdict.

  • Likely unattributed instances of the same symptom: #4180 (Google Search), #13823 (addons.mozilla.org), #3307 (git.sr.ht).

  • Tested with a dev build of main (~4.9.130), Chrome XX (MV3), Windows 11. Repro: load https://pixiv.net with default settings on a warm start.

  • Happy to implement the directive and tests if the direction looks acceptable.

主要语言
TypeScript
星标
22.4k
派生
2.8k
平均合并
23 小时 35 分钟
30 天内合并 PR
57

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

darkreader/darkreader 的其他 Issue

查看 darkreader/darkreader 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。