From 341b1c1c3e2e44690540fb06b9aa140ddcf17fe5 Mon Sep 17 00:00:00 2001 From: Lain Soykaf Date: Tue, 11 Aug 2026 21:51:24 +0400 Subject: [PATCH] fix: restore Theme 2 font families --- changelog.d/theme2-font-cache.fix | 1 + src/services/style_setter/style_setter.js | 8 +++- src/services/theme_data/theme2_to_theme3.js | 2 +- .../style_setter/style_setter.spec.js | 24 +++++++++++ .../theme_data/theme2_to_theme3.spec.js | 42 +++++++++++++++++++ 5 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 changelog.d/theme2-font-cache.fix create mode 100644 test/unit/specs/services/style_setter/style_setter.spec.js create mode 100644 test/unit/specs/services/theme_data/theme2_to_theme3.spec.js diff --git a/changelog.d/theme2-font-cache.fix b/changelog.d/theme2-font-cache.fix new file mode 100644 index 000000000..d8782b467 --- /dev/null +++ b/changelog.d/theme2-font-cache.fix @@ -0,0 +1 @@ +Fix Theme 2 fonts falling back to serif after upgrade diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js index 318978264..d42c5793f 100644 --- a/src/services/style_setter/style_setter.js +++ b/src/services/style_setter/style_setter.js @@ -92,6 +92,11 @@ export const adoptStyleSheets = throttle(() => { const EAGER_STYLE_ID = 'pleroma-eager-styles' const LAZY_STYLE_ID = 'pleroma-lazy-styles' +export const hasInvalidCachedThemeRules = (data) => + data + .flat() + .some((rule) => /--(?:mono)?font:\s*\[object Object\](?:;|$)/i.test(rule)) + const generateTheme = (inputRuleset, callbacks, debug) => { const { onNewRule = () => { @@ -151,7 +156,8 @@ export const tryLoadCache = async () => { if ( cache.engineChecksum === getEngineChecksum() && cache.checksum !== undefined && - cache.checksum === useMergedConfigStore().mergedConfig.themeChecksum + cache.checksum === useMergedConfigStore().mergedConfig.themeChecksum && + !hasInvalidCachedThemeRules(cache.data) ) { const eagerStyles = createStyleSheet(EAGER_STYLE_ID, 10) const lazyStyles = createStyleSheet(LAZY_STYLE_ID, 20) diff --git a/src/services/theme_data/theme2_to_theme3.js b/src/services/theme_data/theme2_to_theme3.js index 8c3ac6ad2..48afe4ad9 100644 --- a/src/services/theme_data/theme2_to_theme3.js +++ b/src/services/theme_data/theme2_to_theme3.js @@ -266,7 +266,7 @@ export const convertTheme2To3 = (data) => { Object.keys(data.fonts || {}).forEach((key) => { if (!fontsKeys.has(key)) return if (!data.fonts[key]) return - const originalFont = data.fonts[key] + const originalFont = data.fonts[key].family const rule = { source: '2to3' } switch (key) { diff --git a/test/unit/specs/services/style_setter/style_setter.spec.js b/test/unit/specs/services/style_setter/style_setter.spec.js new file mode 100644 index 000000000..c1bacdfa1 --- /dev/null +++ b/test/unit/specs/services/style_setter/style_setter.spec.js @@ -0,0 +1,24 @@ +import { hasInvalidCachedThemeRules } from 'src/services/style_setter/style_setter.js' + +describe('style setter cache', () => { + it('rejects cached rules containing serialized objects', () => { + expect( + hasInvalidCachedThemeRules([ + ['html { --font: [object Object]; }'], + ['.post { --font: sans-serif; }'], + ]), + ).to.equal(true) + }) + + it('accepts cached rules containing valid font families', () => { + expect( + hasInvalidCachedThemeRules([ + ['html { --font: sans-serif; }'], + [ + '.post { --font: "Atkinson Hyperlegible"; }', + '.post::after { content: "[object Object]"; }', + ], + ]), + ).to.equal(false) + }) +}) diff --git a/test/unit/specs/services/theme_data/theme2_to_theme3.spec.js b/test/unit/specs/services/theme_data/theme2_to_theme3.spec.js new file mode 100644 index 000000000..7165d88db --- /dev/null +++ b/test/unit/specs/services/theme_data/theme2_to_theme3.spec.js @@ -0,0 +1,42 @@ +import { + basePaletteKeys, + convertTheme2To3, +} from 'src/services/theme_data/theme2_to_theme3.js' + +describe('Theme 2 to Theme 3 conversion', () => { + it('converts font descriptors to CSS font families', () => { + const colors = Object.fromEntries( + [...basePaletteKeys].map((key) => [key, '#000000']), + ) + const rules = convertTheme2To3({ + colors, + fonts: { + interface: { family: 'sans-serif' }, + input: { family: 'Open Sans' }, + post: { family: 'Atkinson Hyperlegible' }, + postCode: { family: 'monospace' }, + }, + }) + + expect(rules).to.deep.include({ + source: '2to3', + component: 'Root', + directives: { '--font': 'generic | sans-serif' }, + }) + expect(rules).to.deep.include({ + source: '2to3', + component: 'Root', + directives: { '--monoFont': 'generic | monospace' }, + }) + expect(rules).to.deep.include({ + source: '2to3', + component: 'Input', + directives: { '--font': 'generic | Open Sans' }, + }) + expect(rules).to.deep.include({ + source: '2to3', + component: 'RichContent', + directives: { '--font': 'generic | Atkinson Hyperlegible' }, + }) + }) +})