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:
		
							parent
							
								
									e89da6d940
								
							
						
					
					
						commit
						1b6a83da4a
					
				@ -24,7 +24,6 @@ import { RenderingCancelledException } from "pdfjs-lib";
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const DRAW_UPSCALE_FACTOR = 2; // See comment in `PDFThumbnailView.draw` below.
 | 
					const DRAW_UPSCALE_FACTOR = 2; // See comment in `PDFThumbnailView.draw` below.
 | 
				
			||||||
const MAX_NUM_SCALING_STEPS = 3;
 | 
					const MAX_NUM_SCALING_STEPS = 3;
 | 
				
			||||||
const THUMBNAIL_CANVAS_BORDER_WIDTH = 1; // px
 | 
					 | 
				
			||||||
const THUMBNAIL_WIDTH = 98; // px
 | 
					const THUMBNAIL_WIDTH = 98; // px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -107,15 +106,6 @@ class PDFThumbnailView {
 | 
				
			|||||||
    this.renderTask = null;
 | 
					    this.renderTask = null;
 | 
				
			||||||
    this.renderingState = RenderingStates.INITIAL;
 | 
					    this.renderingState = RenderingStates.INITIAL;
 | 
				
			||||||
    this.resume = null;
 | 
					    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;
 | 
					    this.l10n = l10n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const anchor = document.createElement("a");
 | 
					    const anchor = document.createElement("a");
 | 
				
			||||||
@ -133,19 +123,30 @@ class PDFThumbnailView {
 | 
				
			|||||||
    div.className = "thumbnail";
 | 
					    div.className = "thumbnail";
 | 
				
			||||||
    div.setAttribute("data-page-number", this.id);
 | 
					    div.setAttribute("data-page-number", this.id);
 | 
				
			||||||
    this.div = div;
 | 
					    this.div = div;
 | 
				
			||||||
 | 
					    this.#updateDims();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const ring = document.createElement("div");
 | 
					    const img = document.createElement("div");
 | 
				
			||||||
    ring.className = "thumbnailSelectionRing";
 | 
					    img.className = "thumbnailImage";
 | 
				
			||||||
    const borderAdjustment = 2 * THUMBNAIL_CANVAS_BORDER_WIDTH;
 | 
					    this._placeholderImg = img;
 | 
				
			||||||
    ring.style.width = this.canvasWidth + borderAdjustment + "px";
 | 
					 | 
				
			||||||
    ring.style.height = this.canvasHeight + borderAdjustment + "px";
 | 
					 | 
				
			||||||
    this.ring = ring;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    div.append(ring);
 | 
					    div.append(img);
 | 
				
			||||||
    anchor.append(div);
 | 
					    anchor.append(div);
 | 
				
			||||||
    container.append(anchor);
 | 
					    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) {
 | 
					  setPdfPage(pdfPage) {
 | 
				
			||||||
    this.pdfPage = pdfPage;
 | 
					    this.pdfPage = pdfPage;
 | 
				
			||||||
    this.pdfPageRotate = pdfPage.rotate;
 | 
					    this.pdfPageRotate = pdfPage.rotate;
 | 
				
			||||||
@ -158,19 +159,9 @@ class PDFThumbnailView {
 | 
				
			|||||||
    this.cancelRendering();
 | 
					    this.cancelRendering();
 | 
				
			||||||
    this.renderingState = RenderingStates.INITIAL;
 | 
					    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");
 | 
					    this.div.removeAttribute("data-loaded");
 | 
				
			||||||
    const ring = this.ring;
 | 
					    this.image?.replaceWith(this._placeholderImg);
 | 
				
			||||||
    ring.textContent = ""; // Remove the thumbnail from the DOM.
 | 
					    this.#updateDims();
 | 
				
			||||||
    const borderAdjustment = 2 * THUMBNAIL_CANVAS_BORDER_WIDTH;
 | 
					 | 
				
			||||||
    ring.style.width = this.canvasWidth + borderAdjustment + "px";
 | 
					 | 
				
			||||||
    ring.style.height = this.canvasHeight + borderAdjustment + "px";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (this.canvas) {
 | 
					    if (this.canvas) {
 | 
				
			||||||
      // Zeroing the width and height causes Firefox to release graphics
 | 
					      // Zeroing the width and height causes Firefox to release graphics
 | 
				
			||||||
@ -243,14 +234,11 @@ class PDFThumbnailView {
 | 
				
			|||||||
    this._thumbPageCanvas.then(msg => {
 | 
					    this._thumbPageCanvas.then(msg => {
 | 
				
			||||||
      image.setAttribute("aria-label", msg);
 | 
					      image.setAttribute("aria-label", msg);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    image.style.width = this.canvasWidth + "px";
 | 
					 | 
				
			||||||
    image.style.height = this.canvasHeight + "px";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    image.src = reducedCanvas.toDataURL();
 | 
					    image.src = reducedCanvas.toDataURL();
 | 
				
			||||||
    this.image = image;
 | 
					    this.image = image;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.div.setAttribute("data-loaded", true);
 | 
					    this.div.setAttribute("data-loaded", true);
 | 
				
			||||||
    this.ring.append(image);
 | 
					    this._placeholderImg.replaceWith(image);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Zeroing the width and height causes Firefox to release graphics
 | 
					    // Zeroing the width and height causes Firefox to release graphics
 | 
				
			||||||
    // resources immediately, which can greatly reduce memory consumption.
 | 
					    // resources immediately, which can greatly reduce memory consumption.
 | 
				
			||||||
 | 
				
			|||||||
@ -60,10 +60,12 @@
 | 
				
			|||||||
  --field-bg-color: rgba(255, 255, 255, 1);
 | 
					  --field-bg-color: rgba(255, 255, 255, 1);
 | 
				
			||||||
  --field-border-color: rgba(187, 187, 188, 1);
 | 
					  --field-border-color: rgba(187, 187, 188, 1);
 | 
				
			||||||
  --treeitem-color: rgba(0, 0, 0, 0.8);
 | 
					  --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-hover-color: rgba(0, 0, 0, 0.9);
 | 
				
			||||||
  --treeitem-selected-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);
 | 
					  --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-bg-color: rgba(255, 255, 255, 1);
 | 
				
			||||||
  --doorhanger-border-color: rgba(12, 12, 13, 0.2);
 | 
					  --doorhanger-border-color: rgba(12, 12, 13, 0.2);
 | 
				
			||||||
  --doorhanger-hover-color: rgba(12, 12, 13, 1);
 | 
					  --doorhanger-hover-color: rgba(12, 12, 13, 1);
 | 
				
			||||||
@ -150,10 +152,12 @@
 | 
				
			|||||||
    --field-bg-color: rgba(64, 64, 68, 1);
 | 
					    --field-bg-color: rgba(64, 64, 68, 1);
 | 
				
			||||||
    --field-border-color: rgba(115, 115, 115, 1);
 | 
					    --field-border-color: rgba(115, 115, 115, 1);
 | 
				
			||||||
    --treeitem-color: rgba(255, 255, 255, 0.8);
 | 
					    --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-hover-color: rgba(255, 255, 255, 0.9);
 | 
				
			||||||
    --treeitem-selected-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);
 | 
					    --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-bg-color: rgba(74, 74, 79, 1);
 | 
				
			||||||
    --doorhanger-border-color: rgba(39, 39, 43, 1);
 | 
					    --doorhanger-border-color: rgba(39, 39, 43, 1);
 | 
				
			||||||
    --doorhanger-hover-color: rgba(249, 249, 250, 1);
 | 
					    --doorhanger-hover-color: rgba(249, 249, 250, 1);
 | 
				
			||||||
@ -1136,56 +1140,49 @@ a:is(.toolbarButton, .secondaryToolbarButton)[href="#"] {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.thumbnail {
 | 
					.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);
 | 
					  float: var(--inline-start);
 | 
				
			||||||
 | 
					  width: var(--thumbnail-width);
 | 
				
			||||||
 | 
					  height: var(--thumbnail-height);
 | 
				
			||||||
  margin: 0 10px 5px;
 | 
					  margin: 0 10px 5px;
 | 
				
			||||||
 | 
					  padding: 1px;
 | 
				
			||||||
 | 
					  border: 7px solid transparent;
 | 
				
			||||||
 | 
					  border-radius: 2px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#thumbnailView > a:last-of-type > .thumbnail {
 | 
					#thumbnailView > a:last-of-type > .thumbnail {
 | 
				
			||||||
  margin-bottom: 10px;
 | 
					  margin-bottom: 10px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#thumbnailView > a:last-of-type > .thumbnail:not([data-loaded]) {
 | 
					 | 
				
			||||||
  margin-bottom: 9px;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
.thumbnail:not([data-loaded]) {
 | 
					a:focus > .thumbnail,
 | 
				
			||||||
  border: 1px dashed rgba(132, 132, 132, 1);
 | 
					.thumbnail:hover {
 | 
				
			||||||
  margin: -1px 9px 4px;
 | 
					  border-color: var(--thumbnail-hover-color);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.thumbnail.selected {
 | 
				
			||||||
 | 
					  border-color: var(--thumbnail-selected-color) !important;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.thumbnailImage {
 | 
					.thumbnailImage {
 | 
				
			||||||
  border: 1px solid rgba(0, 0, 0, 0);
 | 
					  width: var(--thumbnail-width);
 | 
				
			||||||
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(0, 0, 0, 0.3);
 | 
					  height: var(--thumbnail-height);
 | 
				
			||||||
  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 {
 | 
					 | 
				
			||||||
  opacity: 0.9;
 | 
					  opacity: 0.9;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					a:focus > .thumbnail > .thumbnailImage,
 | 
				
			||||||
a:focus > .thumbnail > .thumbnailSelectionRing,
 | 
					.thumbnail:hover > .thumbnailImage {
 | 
				
			||||||
.thumbnail:hover > .thumbnailSelectionRing {
 | 
					  opacity: 0.95;
 | 
				
			||||||
  background-color: var(--sidebaritem-bg-color);
 | 
					}
 | 
				
			||||||
  background-clip: padding-box;
 | 
					.thumbnail.selected > .thumbnailImage {
 | 
				
			||||||
  color: rgba(255, 255, 255, 0.9);
 | 
					  opacity: 1 !important;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.thumbnail.selected > .thumbnailSelectionRing > .thumbnailImage {
 | 
					.thumbnail:not([data-loaded]) > .thumbnailImage {
 | 
				
			||||||
  opacity: 1;
 | 
					  width: calc(var(--thumbnail-width) - 2px);
 | 
				
			||||||
}
 | 
					  height: calc(var(--thumbnail-height) - 2px);
 | 
				
			||||||
 | 
					  border: 1px dashed rgba(132, 132, 132, 1);
 | 
				
			||||||
.thumbnail.selected > .thumbnailSelectionRing {
 | 
					 | 
				
			||||||
  background-color: var(--sidebaritem-bg-color);
 | 
					 | 
				
			||||||
  background-clip: padding-box;
 | 
					 | 
				
			||||||
  color: rgba(255, 255, 255, 1);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.treeWithDeepNesting > .treeItem,
 | 
					.treeWithDeepNesting > .treeItem,
 | 
				
			||||||
@ -1250,7 +1247,7 @@ a:focus > .thumbnail > .thumbnailSelectionRing,
 | 
				
			|||||||
.treeItemToggler:hover + a,
 | 
					.treeItemToggler:hover + a,
 | 
				
			||||||
.treeItemToggler:hover ~ .treeItems,
 | 
					.treeItemToggler:hover ~ .treeItems,
 | 
				
			||||||
.treeItem > a:hover {
 | 
					.treeItem > a:hover {
 | 
				
			||||||
  background-color: var(--sidebaritem-bg-color);
 | 
					  background-color: var(--treeitem-bg-color);
 | 
				
			||||||
  background-clip: padding-box;
 | 
					  background-clip: padding-box;
 | 
				
			||||||
  border-radius: 2px;
 | 
					  border-radius: 2px;
 | 
				
			||||||
  color: var(--treeitem-hover-color);
 | 
					  color: var(--treeitem-hover-color);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user