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';
}