Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions l10n/en-US/viewer.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ pdfjs-spread-even-button =
.title = Join page spreads starting with even-numbered pages
pdfjs-spread-even-button-label = Even Spreads

## Page Dark Mode

pdfjs-page-dark-mode-button =
.title = Page Dark Mode
pdfjs-page-dark-mode-button-label = Page Dark Mode

## Document properties dialog

pdfjs-document-properties-button =
Expand Down
52 changes: 52 additions & 0 deletions web/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,9 @@ const PDFViewerApplication = {
renderingQueue.setThumbnailViewer(this.pdfThumbnailViewer);
}

// Apply the saved page dark mode preference.
this._applyPageDarkMode(AppOptions.get("pageDarkMode"));

// The browsing history is only enabled when the viewer is standalone,
// i.e. not when it is embedded in a web page.
if (!this.isViewerEmbedded && !AppOptions.get("disableHistory")) {
Expand Down Expand Up @@ -2175,6 +2178,45 @@ const PDFViewerApplication = {
// in the 'rotationchanging' event handler.
},

_togglePageDarkMode() {
const newMode = (AppOptions.get("pageDarkMode") + 1) % 3;
AppOptions.set("pageDarkMode", newMode);
},

_applyPageDarkMode(mode) {
const filterMap = {
0: "none",
1: "brightness(0.85) contrast(0.95)",
2: "invert(0.88) hue-rotate(180deg)",
};
const viewer = this.pdfViewer?.viewer;
if (viewer) {
viewer.style.setProperty(
"--page-dark-mode-filter",
filterMap[mode] || "none"
);
}
// Update thumbnail viewer too
const thumbnailContainer = this.pdfThumbnailViewer?.container;
if (thumbnailContainer) {
thumbnailContainer.style.setProperty(
"--page-dark-mode-filter",
filterMap[mode] || "none"
);
}
// Update button label
const button = this.appConfig?.secondaryToolbar?.pageDarkModeButton;
if (button) {
const labelMap = { 0: "Off", 1: "Soft", 2: "Full" };
const label = labelMap[mode] || "Off";
button.setAttribute("data-page-dark-mode", mode);
const span = button.querySelector("span");
if (span) {
span.textContent = `Page Dark Mode: ${label}`;
}
}
},

requestPresentationMode() {
this.pdfPresentationMode?.request();
},
Expand Down Expand Up @@ -2245,6 +2287,16 @@ const PDFViewerApplication = {
);
eventBus.on("rotatecw", this.rotatePages.bind(this, 90), opts);
eventBus.on("rotateccw", this.rotatePages.bind(this, -90), opts);
eventBus.on(
"togglepagedarkmode",
this._togglePageDarkMode.bind(this),
opts
);
eventBus.on(
"pagedarkmode",
evt => this._applyPageDarkMode(evt.value),
opts
);
eventBus.on(
"optionalcontentconfig",
evt => (pdfViewer.optionalContentConfigPromise = evt.promise),
Expand Down
5 changes: 5 additions & 0 deletions web/app_options.js
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,11 @@ const defaultOptions = {
value: 500, // ms
kind: OptionKind.VIEWER,
},
pageDarkMode: {
/** @type {number} */
value: 0,
kind: OptionKind.VIEWER + OptionKind.PREFERENCE + OptionKind.EVENT_DISPATCH,
},
forcePageColors: {
/** @type {boolean} */
value: false,
Expand Down
3 changes: 3 additions & 0 deletions web/images/secondaryToolbarButton-pageDarkMode.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions web/pdf_viewer.css
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@
--hcm-highlight-filter: none;
--hcm-highlight-selected-filter: none;

--page-dark-mode-filter: none;

@media screen and (forced-colors: active) {
--hcm-highlight-filter: invert(100%);
}
Expand All @@ -111,6 +113,7 @@
width: 100%;
height: 100%;
contain: content;
filter: var(--page-dark-mode-filter);

.structTree {
contain: strict;
Expand Down Expand Up @@ -255,3 +258,10 @@
margin: 0 auto;
border: 2px solid transparent;
}

/* Page dark mode filter for thumbnail images.
The CSS variable --page-dark-mode-filter is set on the thumbnails container
by the app and inherited here. */
.thumbnailsView .thumbnailImageContainer img {
filter: var(--page-dark-mode-filter);
}
5 changes: 5 additions & 0 deletions web/secondary_toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ class SecondaryToolbar {
eventName: "imagealttextsettings",
close: true,
},
{
element: options.pageDarkModeButton,
eventName: "togglepagedarkmode",
close: false,
},
{
element: options.documentPropertiesButton,
eventName: "documentproperties",
Expand Down
5 changes: 5 additions & 0 deletions web/viewer.css
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@
--toolbarButton-editorStamp-icon
);
--secondaryToolbarButton-documentProperties-icon: url(images/secondaryToolbarButton-documentProperties.svg);
--secondaryToolbarButton-pageDarkMode-icon: url(images/secondaryToolbarButton-pageDarkMode.svg);
--editorParams-stampAddImage-icon: url(images/toolbarButton-zoomIn.svg);
--comment-edit-button-icon: url(images/comment-editButton.svg);
}
Expand Down Expand Up @@ -1061,6 +1062,10 @@ dialog :link {
#documentProperties::before {
mask-image: var(--secondaryToolbarButton-documentProperties-icon);
}

#pageDarkMode::before {
mask-image: var(--secondaryToolbarButton-pageDarkMode-icon);
}
}
}

Expand Down
12 changes: 12 additions & 0 deletions web/viewer.html
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,18 @@

<div class="horizontalToolbarSeparator"></div>

<button
id="pageDarkMode"
class="toolbarButton labeled"
type="button"
tabindex="0"
data-l10n-id="pdfjs-page-dark-mode-button"
>
<span data-l10n-id="pdfjs-page-dark-mode-button-label">Page Dark Mode</span>
</button>

<div class="horizontalToolbarSeparator"></div>

<button
id="documentProperties"
class="toolbarButton labeled"
Expand Down
1 change: 1 addition & 0 deletions web/viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ function getViewerConfiguration() {
"imageAltTextSettingsSeparator"
),
documentPropertiesButton: document.getElementById("documentProperties"),
pageDarkModeButton: document.getElementById("pageDarkMode"),
},
viewsManager: {
outerContainer: document.getElementById("outerContainer"),
Expand Down