From 1b6a83da4a0f32b309df5e1fb4143df7970f1915 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sun, 30 Apr 2023 11:01:42 +0200 Subject: [PATCH] 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. --- web/pdf_thumbnail_view.js | 54 +++++++++++------------------ web/viewer.css | 73 +++++++++++++++++++-------------------- 2 files changed, 56 insertions(+), 71 deletions(-) diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js index 4fbb4c536..a89c37c70 100644 --- a/web/pdf_thumbnail_view.js +++ b/web/pdf_thumbnail_view.js @@ -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. diff --git a/web/viewer.css b/web/viewer.css index b48b947df..0ecb7a150 100644 --- a/web/viewer.css +++ b/web/viewer.css @@ -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);