diff --git a/src/common/components/modal-popup/theme-popup.js b/src/common/components/modal-popup/theme-popup.js index 19f10d90d..91627f827 100644 --- a/src/common/components/modal-popup/theme-popup.js +++ b/src/common/components/modal-popup/theme-popup.js @@ -88,10 +88,14 @@ function ThemePopup({ params, customThemes, colorScheme, lightTheme, darkTheme, let currentTheme = currentColorScheme === 'light' ? lightTheme : darkTheme; let bg = '#FFFFFF'; let fg = '#000000'; + let lc = '#0000EE'; + let vlc = '#551A8B'; let inv = false; if (currentTheme) { bg = currentTheme.background; fg = currentTheme.foreground; + lc = currentTheme.linkColor || ''; + vlc = currentTheme.visitedLinkColor || ''; inv = currentTheme.invertImages; } @@ -99,6 +103,8 @@ function ThemePopup({ params, customThemes, colorScheme, lightTheme, darkTheme, let [label, setLabel] = useState(params.theme?.label || ''); let [background, setBackground] = useState(params.theme?.background || bg); let [foreground, setForeground] = useState(params.theme?.foreground || fg); + let [linkColor, setLinkColor] = useState(params.theme?.linkColor || params.theme?.foreground || lc); + let [visitedLinkColor, setVisitedLinkColor] = useState(params.theme?.visitedLinkColor || params.theme?.foreground || vlc); let [invertImages, setInvertImages] = useState(params.theme?.invertImages ?? inv); let themeIsDark = isDarkTheme(background, foreground); @@ -136,6 +142,18 @@ function ThemePopup({ params, customThemes, colorScheme, lightTheme, darkTheme, theme.label = label.trim(); theme.background = background; theme.foreground = foreground; + if (linkColor && isValidHexColor(linkColor)) { + theme.linkColor = linkColor; + } + else { + delete theme.linkColor; + } + if (visitedLinkColor && isValidHexColor(visitedLinkColor)) { + theme.visitedLinkColor = visitedLinkColor; + } + else { + delete theme.visitedLinkColor; + } if (invertImages) { theme.invertImages = true; } @@ -181,6 +199,8 @@ function ThemePopup({ params, customThemes, colorScheme, lightTheme, darkTheme, !nameInvalid && isValidHexColor(background) && isValidHexColor(foreground) + && (!linkColor || isValidHexColor(linkColor)) + && (!visitedLinkColor || isValidHexColor(visitedLinkColor)) ); return ( @@ -202,6 +222,10 @@ function ThemePopup({ params, customThemes, colorScheme, lightTheme, darkTheme,
+ +
+ +
diff --git a/src/common/defines.js b/src/common/defines.js index 96f5b633f..c48af2ecf 100644 --- a/src/common/defines.js +++ b/src/common/defines.js @@ -48,10 +48,10 @@ export const INK_ANNOTATION_WIDTH_STEPS = [ export const TEXT_ANNOTATION_FONT_SIZE_STEPS = [6, 8, 10, 12, 14, 18, 24, 36, 48, 64, 72, 96, 144, 192]; export const DEFAULT_THEMES = [ - { id: 'dark', label: 'Dark', background: "#2E3440", foreground: "#D8DEE9" }, - { id: 'black', label: 'Black', background: "#000000", foreground: "#FFFFFF", invertImages: true }, - { id: 'snow', label: 'Snow', background: "#ECEFF4", foreground: "#3B4252" }, - { id: 'sepia', label: 'Sepia', background: "#F4ECD8", foreground: "#5B4636" } + { id: 'dark', label: 'Dark', background: "#2E3440", foreground: "#D8DEE9", linkColor: "#88C0D0", visitedLinkColor: "#6E9FAB" }, + { id: 'black', label: 'Black', background: "#000000", foreground: "#FFFFFF", linkColor: "#6CB6FF", visitedLinkColor: "#5A92CC", invertImages: true }, + { id: 'snow', label: 'Snow', background: "#ECEFF4", foreground: "#3B4252", linkColor: "#4C6E96", visitedLinkColor: "#3D5975" }, + { id: 'sepia', label: 'Sepia', background: "#F4ECD8", foreground: "#5B4636", linkColor: "#8A4F3D", visitedLinkColor: "#6E3F31" } ]; export const A11Y_VIRT_CURSOR_DEBOUNCE_LENGTH = 500; // ms diff --git a/src/common/types.ts b/src/common/types.ts index 7db82cbda..c4314087c 100644 --- a/src/common/types.ts +++ b/src/common/types.ts @@ -223,6 +223,8 @@ export type Theme = { label: string; background: string; foreground: string; + linkColor?: string; + visitedLinkColor?: string; invertImages?: boolean; }; diff --git a/src/dom/common/dom-view.tsx b/src/dom/common/dom-view.tsx index 762b777f2..7761cba47 100644 --- a/src/dom/common/dom-view.tsx +++ b/src/dom/common/dom-view.tsx @@ -848,6 +848,8 @@ abstract class DOMView { root.style.colorScheme = themeColorScheme; root.style.setProperty('--background-color', theme.background); root.style.setProperty('--text-color', theme.foreground); + root.style.setProperty('--link-color', theme.linkColor || theme.foreground); + root.style.setProperty('--visited-link-color', theme.visitedLinkColor || theme.linkColor || theme.foreground); } this._theme = theme; diff --git a/src/dom/epub/stylesheets/_content.scss b/src/dom/epub/stylesheets/_content.scss index 6910294fa..9828e0726 100644 --- a/src/dom/epub/stylesheets/_content.scss +++ b/src/dom/epub/stylesheets/_content.scss @@ -41,15 +41,6 @@ } } -:root { - --link-color: #0000ee; - --visited-link-color: #551a8b; - - &[data-color-scheme="dark"] { - --link-color: #63caff; - --visited-link-color: #0099e5; - } -} :root { font-size: calc(var(--content-scale) * 13pt) !important; diff --git a/src/dom/snapshot/stylesheets/inject.scss b/src/dom/snapshot/stylesheets/inject.scss index 8968c305a..b97125a1e 100644 --- a/src/dom/snapshot/stylesheets/inject.scss +++ b/src/dom/snapshot/stylesheets/inject.scss @@ -19,4 +19,12 @@ body.force-static-theme { background-color: transparent !important; color: var(--text-color); } + + :link { + color: var(--link-color) !important; + } + + :visited { + color: var(--visited-link-color) !important; + } } diff --git a/src/dom/snapshot/stylesheets/reading-mode.scss b/src/dom/snapshot/stylesheets/reading-mode.scss index a2ccdbd54..1dea0be04 100644 --- a/src/dom/snapshot/stylesheets/reading-mode.scss +++ b/src/dom/snapshot/stylesheets/reading-mode.scss @@ -20,13 +20,6 @@ background-color: var(--background-color); color: var(--text-color); - --link-color: #0000ee; - --visited-link-color: #551a8b; - - &[data-color-scheme="dark"] { - --link-color: #63caff; - --visited-link-color: #0099e5; - } } body { diff --git a/src/pdf/pdf-view.js b/src/pdf/pdf-view.js index cd9fe8821..1c9cd1647 100644 --- a/src/pdf/pdf-view.js +++ b/src/pdf/pdf-view.js @@ -543,16 +543,22 @@ class PDFView { if (this._colorScheme === 'light' && this._lightTheme) { this._iframeWindow.theme = this._lightTheme; root.style.setProperty('--background-color', this._lightTheme.background); + root.style.setProperty('--link-color', this._lightTheme.linkColor || this._lightTheme.foreground); + root.style.setProperty('--visited-link-color', this._lightTheme.visitedLinkColor || this._lightTheme.linkColor || this._lightTheme.foreground); this._themeColorScheme = getModeBasedOnColors(this._lightTheme.background, this._lightTheme.foreground); } else if (this._colorScheme === 'dark' && this._darkTheme) { this._iframeWindow.theme = this._darkTheme; root.style.setProperty('--background-color', this._darkTheme.background); + root.style.setProperty('--link-color', this._darkTheme.linkColor || this._darkTheme.foreground); + root.style.setProperty('--visited-link-color', this._darkTheme.visitedLinkColor || this._darkTheme.linkColor || this._darkTheme.foreground); this._themeColorScheme = getModeBasedOnColors(this._darkTheme.background, this._darkTheme.foreground); } else { this._iframeWindow.theme = null; root.style.setProperty('--background-color', '#FFFFFF'); + root.style.setProperty('--link-color', '#121212'); + root.style.setProperty('--visited-link-color', '#121212'); this._themeColorScheme = 'light'; }