From 9d8062ae2753286b823aa26df819a3c73295d28d Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Wed, 3 Jun 2026 00:20:59 +0800 Subject: [PATCH] fix(reader): keep table background matching the page in dark mode (#4419) (#4426) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dark-mode `table *` color-mix tint in getColorStyles was applied unconditionally since #4055, so plain tables — and the invisible spacer cells some books use for vertical TOC layout — rendered a few shades off the page background, and the spacing between words appeared to change. Restore the `overrideColor` gate that #2377 originally added. Illegible light/zebra table backgrounds (the #4028 case #4055 targeted) are now handled separately by the dark-mode light-background rewriters from #4392, so the blanket tint is no longer needed by default. The standalone blockquote tint stays unconditional in dark mode. Co-authored-by: Claude Opus 4.8 (1M context) --- .../__tests__/utils/style-get-styles.test.ts | 27 +++++++++++++++++++ apps/readest-app/src/utils/style.ts | 11 ++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/apps/readest-app/src/__tests__/utils/style-get-styles.test.ts b/apps/readest-app/src/__tests__/utils/style-get-styles.test.ts index 81683870..c7434ff1 100644 --- a/apps/readest-app/src/__tests__/utils/style-get-styles.test.ts +++ b/apps/readest-app/src/__tests__/utils/style-get-styles.test.ts @@ -639,6 +639,33 @@ describe('getColorStyles branches (via getStyles)', () => { ); }); + it('does not tint table descendants in dark mode when overrideColor is false (#4419)', () => { + const vs = makeViewSettings({ overrideColor: false }); + const theme = makeThemeCode({ isDarkMode: true, bg: '#1a1a1a', fg: '#e0e0e0' }); + const css = getStyles(vs, theme); + // When the user has NOT enabled color override, the `blockquote, table *` + // rule must not paint a tinted background on table descendants. Otherwise + // plain tables — and the invisible spacer cells some books use for vertical + // layout — render with a color different from the page background, and the + // spacing between words appears to change in dark mode. Regression from + // #4055; the #4028 zebra-row legibility case is now handled by the + // light-background rewriters from #4392. See issue #4419. + const match = css.match(/blockquote,\s*table\s*\*\s*\{([^}]*)\}/); + expect(match).not.toBeNull(); + expect(match![1]).not.toContain('color-mix'); + }); + + it('still tints blockquotes in dark mode when overrideColor is false', () => { + const vs = makeViewSettings({ overrideColor: false }); + const theme = makeThemeCode({ isDarkMode: true, bg: '#1a1a1a', fg: '#e0e0e0' }); + const css = getStyles(vs, theme); + // The standalone `blockquote` rule keeps its dark-mode tint regardless of + // overrideColor — only the shared `table *` part is gated. + expect(css).toMatch( + /blockquote\s*\{[^}]*background:\s*color-mix\(in srgb,\s*#1a1a1a\s*80%,\s*#000\)/, + ); + }); + it('makes svg/img backgrounds transparent when overrideColor is true', () => { const vs = makeViewSettings({ overrideColor: true }); const theme = makeThemeCode(); diff --git a/apps/readest-app/src/utils/style.ts b/apps/readest-app/src/utils/style.ts index 6836bedb..1be89043 100644 --- a/apps/readest-app/src/utils/style.ts +++ b/apps/readest-app/src/utils/style.ts @@ -258,9 +258,16 @@ const getColorStyles = ( blockquote { ${isDarkMode ? `background: color-mix(in srgb, ${bg} 80%, #000);` : ''} } + /* Only tint table descendants when the user has opted into color override. + By default, leave them transparent so a plain table (and the invisible + spacer cells some books use for vertical layout) keeps the page + background instead of a different shade. Illegible light/zebra table + backgrounds are handled separately by the dark-mode light-background + rewriters (getDarkModeLightBackgroundOverrides / transformStylesheet). + See #4419 (and #2377, which this gate originally fixed). */ blockquote, table * { - ${isDarkMode ? `background: color-mix(in srgb, ${bg} 80%, #000);` : ''} - ${isDarkMode ? `background-color: color-mix(in srgb, ${bg} 80%, #000);` : ''} + ${isDarkMode && overrideColor ? `background: color-mix(in srgb, ${bg} 80%, #000);` : ''} + ${isDarkMode && overrideColor ? `background-color: color-mix(in srgb, ${bg} 80%, #000);` : ''} } /* override inline hardcoded text color */ font[color="#000000"], font[color="#000"], font[color="black"],