Simplify the thumbnail styling in the viewer

This patch tries to simplify, and improve, the thumbnail styling:
 - For rendered thumbnails there's one less DOM-element per thumbnail, which can't hurt in longer documents.
 - Use CSS-variables to set the dimensions of all relevant DOM-elements at once.
 - Simplify the visual styling of the thumbnails, e.g. remove the border since the viewer no longer has visible borders around pages, since the relevant CSS-rules are quite old code.
   These changes also, at least in my opinion, makes the relevant CSS-rules much easier to understand and work with.
 - Make it easier to work on e.g. [bug 1690428](https://bugzilla.mozilla.org/show_bug.cgi?id=1690428) without affecting the other sidebarViews.
This commit is contained in:
Jonas Jenwald 2023-04-30 11:01:42 +02:00
parent e89da6d940
commit 1b6a83da4a
2 changed files with 56 additions and 71 deletions

View File

@ -24,7 +24,6 @@ import { RenderingCancelledException } from "pdfjs-lib";
const DRAW_UPSCALE_FACTOR = 2; // See comment in `PDFThumbnailView.draw` below.
const MAX_NUM_SCALING_STEPS = 3;
const THUMBNAIL_CANVAS_BORDER_WIDTH = 1; // px
const THUMBNAIL_WIDTH = 98; // px
/**
@ -107,15 +106,6 @@ class PDFThumbnailView {
this.renderTask = null;
this.renderingState = RenderingStates.INITIAL;
this.resume = null;
const pageWidth = this.viewport.width,
pageHeight = this.viewport.height,
pageRatio = pageWidth / pageHeight;
this.canvasWidth = THUMBNAIL_WIDTH;
this.canvasHeight = (this.canvasWidth / pageRatio) | 0;
this.scale = this.canvasWidth / pageWidth;
this.l10n = l10n;
const anchor = document.createElement("a");
@ -133,19 +123,30 @@ class PDFThumbnailView {
div.className = "thumbnail";
div.setAttribute("data-page-number", this.id);
this.div = div;
this.#updateDims();
const ring = document.createElement("div");
ring.className = "thumbnailSelectionRing";
const borderAdjustment = 2 * THUMBNAIL_CANVAS_BORDER_WIDTH;
ring.style.width = this.canvasWidth + borderAdjustment + "px";
ring.style.height = this.canvasHeight + borderAdjustment + "px";
this.ring = ring;
const img = document.createElement("div");
img.className = "thumbnailImage";
this._placeholderImg = img;
div.append(ring);
div.append(img);
anchor.append(div);
container.append(anchor);
}
#updateDims() {
const { width, height } = this.viewport;
const ratio = width / height;
this.canvasWidth = THUMBNAIL_WIDTH;
this.canvasHeight = (this.canvasWidth / ratio) | 0;
this.scale = this.canvasWidth / width;
const { style } = this.div;
style.setProperty("--thumbnail-width", `${this.canvasWidth}px`);
style.setProperty("--thumbnail-height", `${this.canvasHeight}px`);
}
setPdfPage(pdfPage) {
this.pdfPage = pdfPage;
this.pdfPageRotate = pdfPage.rotate;
@ -158,19 +159,9 @@ class PDFThumbnailView {
this.cancelRendering();
this.renderingState = RenderingStates.INITIAL;
const pageWidth = this.viewport.width,
pageHeight = this.viewport.height,
pageRatio = pageWidth / pageHeight;
this.canvasHeight = (this.canvasWidth / pageRatio) | 0;
this.scale = this.canvasWidth / pageWidth;
this.div.removeAttribute("data-loaded");
const ring = this.ring;
ring.textContent = ""; // Remove the thumbnail from the DOM.
const borderAdjustment = 2 * THUMBNAIL_CANVAS_BORDER_WIDTH;
ring.style.width = this.canvasWidth + borderAdjustment + "px";
ring.style.height = this.canvasHeight + borderAdjustment + "px";
this.image?.replaceWith(this._placeholderImg);
this.#updateDims();
if (this.canvas) {
// Zeroing the width and height causes Firefox to release graphics
@ -243,14 +234,11 @@ class PDFThumbnailView {
this._thumbPageCanvas.then(msg => {
image.setAttribute("aria-label", msg);
});
image.style.width = this.canvasWidth + "px";
image.style.height = this.canvasHeight + "px";
image.src = reducedCanvas.toDataURL();
this.image = image;
this.div.setAttribute("data-loaded", true);
this.ring.append(image);
this._placeholderImg.replaceWith(image);
// Zeroing the width and height causes Firefox to release graphics
// resources immediately, which can greatly reduce memory consumption.

View File

@ -60,10 +60,12 @@
--field-bg-color: rgba(255, 255, 255, 1);
--field-border-color: rgba(187, 187, 188, 1);
--treeitem-color: rgba(0, 0, 0, 0.8);
--treeitem-bg-color: rgba(0, 0, 0, 0.15);
--treeitem-hover-color: rgba(0, 0, 0, 0.9);
--treeitem-selected-color: rgba(0, 0, 0, 0.9);
--treeitem-selected-bg-color: rgba(0, 0, 0, 0.25);
--sidebaritem-bg-color: rgba(0, 0, 0, 0.15);
--thumbnail-hover-color: rgba(0, 0, 0, 0.1);
--thumbnail-selected-color: rgba(0, 0, 0, 0.2);
--doorhanger-bg-color: rgba(255, 255, 255, 1);
--doorhanger-border-color: rgba(12, 12, 13, 0.2);
--doorhanger-hover-color: rgba(12, 12, 13, 1);
@ -150,10 +152,12 @@
--field-bg-color: rgba(64, 64, 68, 1);
--field-border-color: rgba(115, 115, 115, 1);
--treeitem-color: rgba(255, 255, 255, 0.8);
--treeitem-bg-color: rgba(255, 255, 255, 0.15);
--treeitem-hover-color: rgba(255, 255, 255, 0.9);
--treeitem-selected-color: rgba(255, 255, 255, 0.9);
--treeitem-selected-bg-color: rgba(255, 255, 255, 0.25);
--sidebaritem-bg-color: rgba(255, 255, 255, 0.15);
--thumbnail-hover-color: rgba(255, 255, 255, 0.1);
--thumbnail-selected-color: rgba(255, 255, 255, 0.2);
--doorhanger-bg-color: rgba(74, 74, 79, 1);
--doorhanger-border-color: rgba(39, 39, 43, 1);
--doorhanger-hover-color: rgba(249, 249, 250, 1);
@ -1136,56 +1140,49 @@ a:is(.toolbarButton, .secondaryToolbarButton)[href="#"] {
}
.thumbnail {
/* Define these variables here, and not in :root, since the individual
thumbnails may have different sizes. */
--thumbnail-width: 0;
--thumbnail-height: 0;
float: var(--inline-start);
width: var(--thumbnail-width);
height: var(--thumbnail-height);
margin: 0 10px 5px;
padding: 1px;
border: 7px solid transparent;
border-radius: 2px;
}
#thumbnailView > a:last-of-type > .thumbnail {
margin-bottom: 10px;
}
#thumbnailView > a:last-of-type > .thumbnail:not([data-loaded]) {
margin-bottom: 9px;
}
.thumbnail:not([data-loaded]) {
border: 1px dashed rgba(132, 132, 132, 1);
margin: -1px 9px 4px;
a:focus > .thumbnail,
.thumbnail:hover {
border-color: var(--thumbnail-hover-color);
}
.thumbnail.selected {
border-color: var(--thumbnail-selected-color) !important;
}
.thumbnailImage {
border: 1px solid rgba(0, 0, 0, 0);
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(0, 0, 0, 0.3);
opacity: 0.8;
z-index: 99;
background-color: rgba(255, 255, 255, 1);
background-clip: content-box;
}
.thumbnailSelectionRing {
border-radius: 2px;
padding: 7px;
}
a:focus > .thumbnail > .thumbnailSelectionRing > .thumbnailImage,
.thumbnail:hover > .thumbnailSelectionRing > .thumbnailImage {
width: var(--thumbnail-width);
height: var(--thumbnail-height);
opacity: 0.9;
}
a:focus > .thumbnail > .thumbnailSelectionRing,
.thumbnail:hover > .thumbnailSelectionRing {
background-color: var(--sidebaritem-bg-color);
background-clip: padding-box;
color: rgba(255, 255, 255, 0.9);
a:focus > .thumbnail > .thumbnailImage,
.thumbnail:hover > .thumbnailImage {
opacity: 0.95;
}
.thumbnail.selected > .thumbnailImage {
opacity: 1 !important;
}
.thumbnail.selected > .thumbnailSelectionRing > .thumbnailImage {
opacity: 1;
}
.thumbnail.selected > .thumbnailSelectionRing {
background-color: var(--sidebaritem-bg-color);
background-clip: padding-box;
color: rgba(255, 255, 255, 1);
.thumbnail:not([data-loaded]) > .thumbnailImage {
width: calc(var(--thumbnail-width) - 2px);
height: calc(var(--thumbnail-height) - 2px);
border: 1px dashed rgba(132, 132, 132, 1);
}
.treeWithDeepNesting > .treeItem,
@ -1250,7 +1247,7 @@ a:focus > .thumbnail > .thumbnailSelectionRing,
.treeItemToggler:hover + a,
.treeItemToggler:hover ~ .treeItems,
.treeItem > a:hover {
background-color: var(--sidebaritem-bg-color);
background-color: var(--treeitem-bg-color);
background-clip: padding-box;
border-radius: 2px;
color: var(--treeitem-hover-color);