added filter toggle button
- new `string-template` and `renderStringPref` (regex pattern matching) in chromium extension options - new `cssInvertPage`, `cssInvertThumb`, and `cssInvertFilter` settings (with defaults; off by default) - available filters: `brightness()`, `contrast()`, `grayscale()`, `invert()`, `sepia()`, `saturate()`, and `hue-rotate()` via regex (valid CSS syntax) - translations for `en-US`, `en-GB`, `en-CA`, and `de` - filter influences PDF view container and PDF thmbnail container (thus also custom text/drawings/highlights) - new svg as icon (modified `toolbarButton-editorStamp.svg`) - button toggle is added next to zoom/scale controls in the middle of the toolbar
This commit is contained in:
parent
8460d903e2
commit
6cb11e420a
@ -43,6 +43,15 @@ input:invalid {
|
||||
<div id="settings-boxes"></div>
|
||||
<button id="reset-button" type="button">Restore default settings</button>
|
||||
|
||||
<template id="string-template">
|
||||
<div class="settings-row">
|
||||
<label>
|
||||
<span></span>
|
||||
<input type="text" value="" pattern="" placeholder="">
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="number-template">
|
||||
<div class="settings-row">
|
||||
<label>
|
||||
|
||||
@ -105,6 +105,14 @@ Promise.all([
|
||||
"1",
|
||||
String(prefSchema.default)
|
||||
);
|
||||
} else if (prefSchema.type === "string") {
|
||||
renderPreference = renderStringPref(
|
||||
prefSchema.title,
|
||||
prefSchema.description,
|
||||
prefName,
|
||||
prefSchema.pattern,
|
||||
prefSchema.default
|
||||
);
|
||||
} else {
|
||||
// Should NEVER be reached. Only happens if a new type of preference is
|
||||
// added to the storage manifest.
|
||||
@ -212,6 +220,42 @@ function renderNumberPref(
|
||||
return renderPreference;
|
||||
}
|
||||
|
||||
function renderStringPref(
|
||||
shortDescription,
|
||||
description,
|
||||
prefName,
|
||||
pattern,
|
||||
placeholder
|
||||
) {
|
||||
var wrapper = importTemplate("string-template");
|
||||
var textInput = wrapper.querySelector("input");
|
||||
textInput.pattern = pattern;
|
||||
textInput.placeholder = placeholder;
|
||||
textInput.oninput = function () {
|
||||
textInput.setCustomValidity(
|
||||
textInput.validity.patternMismatch
|
||||
? "Invalid value will not be saved!"
|
||||
: ""
|
||||
);
|
||||
};
|
||||
textInput.onchange = function () {
|
||||
if (!textInput.reportValidity()) {
|
||||
return;
|
||||
}
|
||||
var pref = {};
|
||||
pref[prefName] = this.value;
|
||||
storageArea.set(pref);
|
||||
};
|
||||
wrapper.querySelector("span").textContent = shortDescription;
|
||||
wrapper.querySelector("label").title = description;
|
||||
document.getElementById("settings-boxes").append(wrapper);
|
||||
|
||||
function renderPreference(value) {
|
||||
textInput.value = value;
|
||||
}
|
||||
return renderPreference;
|
||||
}
|
||||
|
||||
function renderBooleanPref(shortDescription, description, prefName) {
|
||||
var wrapper = importTemplate("checkbox-template");
|
||||
var checkbox = wrapper.querySelector('input[type="checkbox"]');
|
||||
|
||||
@ -8,6 +8,25 @@
|
||||
"enum": [0, 1, 2],
|
||||
"default": 2
|
||||
},
|
||||
"cssInvertPage": {
|
||||
"title": "Default brightness inversion",
|
||||
"description": "Toggle on brightness inversion by default.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"cssInvertThumb": {
|
||||
"title": "Brightness invert thubnails",
|
||||
"description": "Also apply brightness inversion for the page thubnails in the sidebar.",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"cssInvertFilter": {
|
||||
"title": "Brightness inversion CSS filter",
|
||||
"description": "The CSS filter used for the toggle. Available filters: 'brightness()', 'contrast()', 'grayscale()', 'invert()', 'sepia()', 'saturate()', and 'hue-rotate()'.",
|
||||
"type": "string",
|
||||
"pattern": "(?: *(?:brightness|contrast|grayscale|invert|sepia|saturate)\\( *(?:[+\\-]?(?:[0-9]+(?:\\.[0-9]+)?|[0-9]*\\.[0-9]+)(?:[eE][+\\-]?[0-9]+)?%? *)?\\)| *hue-rotate\\( *(?:0 *|[+\\-]?(?:[0-9]+(?:\\.[0-9]+)?|[0-9]*\\.[0-9]+)(?:[eE][+\\-]?[0-9]+)?(?:deg|g?rad|turn) *)?\\))+ *",
|
||||
"default": "invert(90%) hue-rotate(180deg)"
|
||||
},
|
||||
"showPreviousViewOnLoad": {
|
||||
"description": "DEPRECATED. Set viewOnLoad to 1 to disable showing the last page/position on load.",
|
||||
"type": "boolean",
|
||||
|
||||
@ -30,6 +30,10 @@ pdfjs-zoom-in-button =
|
||||
pdfjs-zoom-in-button-label = Vergrößern
|
||||
pdfjs-zoom-select =
|
||||
.title = Zoom
|
||||
pdfjs-invert-button =
|
||||
.title = Invertierte Helligkeit umschalten
|
||||
pdfjs-invert-button-label = Helligkeit umkehren
|
||||
.title = Invert brightness
|
||||
pdfjs-presentation-mode-button =
|
||||
.title = In Präsentationsmodus wechseln
|
||||
pdfjs-presentation-mode-button-label = Präsentationsmodus
|
||||
|
||||
@ -30,6 +30,10 @@ pdfjs-zoom-in-button =
|
||||
pdfjs-zoom-in-button-label = Zoom In
|
||||
pdfjs-zoom-select =
|
||||
.title = Zoom
|
||||
pdfjs-invert-button =
|
||||
.title = Toggle inverted brightness
|
||||
pdfjs-invert-button-label = Invert brightness
|
||||
.title = Invert brightness
|
||||
pdfjs-presentation-mode-button =
|
||||
.title = Switch to Presentation Mode
|
||||
pdfjs-presentation-mode-button-label = Presentation Mode
|
||||
|
||||
@ -30,6 +30,10 @@ pdfjs-zoom-in-button =
|
||||
pdfjs-zoom-in-button-label = Zoom In
|
||||
pdfjs-zoom-select =
|
||||
.title = Zoom
|
||||
pdfjs-invert-button =
|
||||
.title = Toggle inverted brightness
|
||||
pdfjs-invert-button-label = Invert brightness
|
||||
.title = Invert brightness
|
||||
pdfjs-presentation-mode-button =
|
||||
.title = Switch to Presentation Mode
|
||||
pdfjs-presentation-mode-button-label = Presentation Mode
|
||||
|
||||
@ -33,6 +33,10 @@ pdfjs-zoom-in-button =
|
||||
pdfjs-zoom-in-button-label = Zoom In
|
||||
pdfjs-zoom-select =
|
||||
.title = Zoom
|
||||
pdfjs-invert-button =
|
||||
.title = Toggle inverted brightness
|
||||
pdfjs-invert-button-label = Invert brightness
|
||||
.title = Invert brightness
|
||||
pdfjs-presentation-mode-button =
|
||||
.title = Switch to Presentation Mode
|
||||
pdfjs-presentation-mode-button-label = Presentation Mode
|
||||
|
||||
14
web/app.js
14
web/app.js
@ -219,6 +219,8 @@ const PDFViewerApplication = {
|
||||
docStyle.setProperty("color-scheme", mode);
|
||||
}
|
||||
|
||||
onInvert.call(this);
|
||||
|
||||
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
|
||||
if (AppOptions.get("enableFakeMLManager")) {
|
||||
this.mlManager =
|
||||
@ -2019,6 +2021,7 @@ const PDFViewerApplication = {
|
||||
eventBus._on("zoomin", this.zoomIn.bind(this), opts);
|
||||
eventBus._on("zoomout", this.zoomOut.bind(this), opts);
|
||||
eventBus._on("zoomreset", this.zoomReset.bind(this), opts);
|
||||
eventBus._on("invert", onInvert.bind(this), opts);
|
||||
eventBus._on("pagenumberchanged", onPageNumberChanged.bind(this), opts);
|
||||
eventBus._on(
|
||||
"scalechanged",
|
||||
@ -2445,6 +2448,17 @@ function onNamedAction(evt) {
|
||||
}
|
||||
}
|
||||
|
||||
function onInvert(evt) {
|
||||
// Handle brightness inversion (CSS filter) toggle
|
||||
const active = evt?.state ?? AppOptions.get("cssInvertPage");
|
||||
const filter = AppOptions.get("cssInvertFilter");
|
||||
this.appConfig.toolbar.invert.classList.toggle("toggled", active);
|
||||
this.appConfig.toolbar.invert.ariaChecked = String(active);
|
||||
this.appConfig.viewerContainer.style.filter = active ? filter : "";
|
||||
this.appConfig.sidebar.thumbnailView.style.filter =
|
||||
active && AppOptions.get("cssInvertThumb") ? filter : "";
|
||||
}
|
||||
|
||||
function onSidebarViewChanged({ view }) {
|
||||
this.pdfRenderingQueue.isThumbnailViewEnabled = view === SidebarView.THUMBS;
|
||||
|
||||
|
||||
@ -178,6 +178,21 @@ const defaultOptions = {
|
||||
value: 0,
|
||||
kind: OptionKind.VIEWER + OptionKind.PREFERENCE,
|
||||
},
|
||||
cssInvertPage: {
|
||||
/** @type {boolean} */
|
||||
value: false,
|
||||
kind: OptionKind.VIEWER + OptionKind.PREFERENCE,
|
||||
},
|
||||
cssInvertThumb: {
|
||||
/** @type {boolean} */
|
||||
value: true,
|
||||
kind: OptionKind.VIEWER + OptionKind.PREFERENCE,
|
||||
},
|
||||
cssInvertFilter: {
|
||||
/** @type {string} */
|
||||
value: "invert(90%) hue-rotate(180deg)",
|
||||
kind: OptionKind.VIEWER + OptionKind.PREFERENCE,
|
||||
},
|
||||
debuggerSrc: {
|
||||
/** @type {string} */
|
||||
value: "./debugger.mjs",
|
||||
|
||||
12
web/images/toolbarButton-invert.svg
Normal file
12
web/images/toolbarButton-invert.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="black">
|
||||
<path d="
|
||||
M3 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-10a2 2 0 0 0-2-2z
|
||||
M5 12a1 1 0 0 1-1-1v-1.321a.75.75 0 0 1 .218-.529L6.35 7.005a.75.75 0 0 1 1.061-.003l2.112 2.102.612-.577a.75.75 0 0 1 1.047.017l.6.605a.75.75 0 0 1 .218.529L12 11a1 1 0 0 1-1 1z
|
||||
M11.6 5m.4.4v1.2l-.4.4h-1.2l-.4-.4v-1.2l.4-.4h1.2z
|
||||
M14 13l-1 1h-10l-1-1v-10l1-1h10l1 1z
|
||||
M13.5 12.75l-.75.75h-9.5l-.75-.75v-9.5l.75-.75h9.5l.75.75z
|
||||
" fill-rule="evenodd"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 772 B |
@ -38,6 +38,8 @@ import {
|
||||
* @property {HTMLButtonElement} next - Button to go to the next page.
|
||||
* @property {HTMLButtonElement} zoomIn - Button to zoom in the pages.
|
||||
* @property {HTMLButtonElement} zoomOut - Button to zoom out the pages.
|
||||
* @property {HTMLButtonElement} invert - Button to toggle brightness inversion
|
||||
* (CSS filter).
|
||||
* @property {HTMLButtonElement} editorFreeTextButton - Button to switch to
|
||||
* FreeText editing.
|
||||
* @property {HTMLButtonElement} download - Button to download the document.
|
||||
@ -67,6 +69,16 @@ class Toolbar {
|
||||
{ element: options.zoomOut, eventName: "zoomout" },
|
||||
{ element: options.print, eventName: "print" },
|
||||
{ element: options.download, eventName: "download" },
|
||||
{
|
||||
element: options.invert,
|
||||
eventName: "invert",
|
||||
eventDetails: {
|
||||
get state() {
|
||||
const { classList } = options.invert;
|
||||
return !classList.contains("toggled");
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
element: options.editorFreeTextButton,
|
||||
eventName: "switchannotationeditormode",
|
||||
|
||||
@ -111,6 +111,7 @@
|
||||
--toolbarButton-pageDown-icon: url(images/toolbarButton-pageDown.svg);
|
||||
--toolbarButton-zoomOut-icon: url(images/toolbarButton-zoomOut.svg);
|
||||
--toolbarButton-zoomIn-icon: url(images/toolbarButton-zoomIn.svg);
|
||||
--toolbarButton-invert-icon: url(images/toolbarButton-invert.svg);
|
||||
--toolbarButton-presentationMode-icon: url(images/toolbarButton-presentationMode.svg);
|
||||
--toolbarButton-print-icon: url(images/toolbarButton-print.svg);
|
||||
/*#if GENERIC*/
|
||||
@ -540,6 +541,10 @@ body {
|
||||
mask-image: var(--toolbarButton-zoomIn-icon);
|
||||
}
|
||||
|
||||
#invertButton::before {
|
||||
mask-image: var(--toolbarButton-invert-icon);
|
||||
}
|
||||
|
||||
#editorFreeTextButton::before {
|
||||
mask-image: var(--toolbarButton-editorFreeText-icon);
|
||||
}
|
||||
|
||||
@ -242,6 +242,9 @@ See https://github.com/adobe-type-tools/cmap-resources
|
||||
<option value="4" data-l10n-id="pdfjs-page-scale-percent" data-l10n-args='{ "scale": 400 }'></option>
|
||||
</select>
|
||||
</span>
|
||||
<button id="invertButton" class="toolbarButton" type="button" tabindex="0" data-l10n-id="pdfjs-invert-button" role="checkbox" aria-checked="false">
|
||||
<span data-l10n-id="pdfjs-invert-button-label"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div id="toolbarViewerRight" class="toolbarHorizontalGroup">
|
||||
<div id="editorModeButtons" class="toolbarHorizontalGroup" role="radiogroup">
|
||||
|
||||
@ -44,6 +44,7 @@ function getViewerConfiguration() {
|
||||
next: document.getElementById("next"),
|
||||
zoomIn: document.getElementById("zoomInButton"),
|
||||
zoomOut: document.getElementById("zoomOutButton"),
|
||||
invert: document.getElementById("invertButton"),
|
||||
print: document.getElementById("printButton"),
|
||||
editorFreeTextButton: document.getElementById("editorFreeTextButton"),
|
||||
editorFreeTextParamsToolbar: document.getElementById(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user