diff --git a/extensions/chromium/preferences_schema.json b/extensions/chromium/preferences_schema.json index 0723e6aede6c16..de2ae62dfb2018 100644 --- a/extensions/chromium/preferences_schema.json +++ b/extensions/chromium/preferences_schema.json @@ -198,6 +198,15 @@ 2 ], "default": -1 + }, + "viewerCssTheme": { + "type": "integer", + "enum": [ + 0, + 1, + 2 + ], + "default": 0 } } } diff --git a/web/app.js b/web/app.js index 0a2fa253207cb3..72d34c601b755c 100644 --- a/web/app.js +++ b/web/app.js @@ -90,6 +90,12 @@ const ViewOnLoad = { INITIAL: 1, }; +const ViewerCssTheme = { + AUTOMATIC: 0, // Default value. + LIGHT: 1, + DARK: 2, +}; + // Keep these in sync with mozilla-central's Histograms.json. const KNOWN_VERSIONS = [ "1.0", @@ -256,6 +262,7 @@ const PDFViewerApplication = { await this._readPreferences(); await this._parseHashParameters(); + this._forceCssTheme(); await this._initializeL10n(); if ( @@ -396,6 +403,45 @@ const PDFViewerApplication = { document.getElementsByTagName("html")[0].dir = dir; }, + /** + * @private + */ + _forceCssTheme() { + const cssTheme = AppOptions.get("viewerCssTheme"); + if ( + cssTheme === ViewerCssTheme.AUTOMATIC || + !Object.values(ViewerCssTheme).includes(cssTheme) + ) { + return; + } + const styleSheet = document.styleSheets[0]; + if (!styleSheet) { + return; + } + const cssRules = styleSheet.cssRules; + for (let i = 0, ii = cssRules.length; i < ii; i++) { + const rule = cssRules[i]; + if ( + rule instanceof CSSMediaRule && + rule.media[0] === "(prefers-color-scheme: dark)" + ) { + if (cssTheme === ViewerCssTheme.LIGHT) { + styleSheet.deleteRule(i); + return; + } + // cssTheme === ViewerCssTheme.DARK + const darkRules = /^@media \(prefers-color-scheme: dark\) {\n\s*([\w\s-.,:;/\\{}()]+)\n}$/.exec( + rule.cssText + ); + if (darkRules?.[1]) { + styleSheet.deleteRule(i); + styleSheet.insertRule(darkRules[1], i); + } + return; + } + } + }, + /** * @private */ diff --git a/web/app_options.js b/web/app_options.js index 2e04ed0a41fb81..e4931997b2f078 100644 --- a/web/app_options.js +++ b/web/app_options.js @@ -154,6 +154,11 @@ const defaultOptions = { value: false, kind: OptionKind.VIEWER + OptionKind.PREFERENCE, }, + viewerCssTheme: { + /** @type {number} */ + value: 0, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE, + }, viewOnLoad: { /** @type {boolean} */ value: 0,