From 82416d4b1937d46f3983fece9b0f44358677668a Mon Sep 17 00:00:00 2001 From: Jonas Jenwald <jonas.jenwald@gmail.com> Date: Fri, 9 Feb 2018 14:25:16 +0100 Subject: [PATCH] Refactor `PDFThumbnailViewer.scrollThumbnailIntoView` to avoid unnecessary DOM look-ups The code responsible for highlighting/scrolling thumbnails is quite old, and parts of it hasn't really changed much over time. In particular, the `scrollThumbnailIntoView` method is currently using `document.querySelector` in order to find both the new/current thumbnail element. This seems totally unnessary, since we can easily keep track of the current thumbnail (similar to the "regular" viewer) and thus avoid unnecessary DOM look-ups. Furthermore, note how the `PDFThumbnailView` constructor is currently highlighting the *first* thumbnail. This is yet another leftover from older viewer code, which we can now remove and instead take care of in `PDFThumbnailViewer.setDocument`. Given that `PDFThumbnailView` does not, nor should it, have any concept of which thumbnail is currently selected, this change also improves the general structure of this code a tiny bit. --- web/pdf_thumbnail_view.js | 6 ------ web/pdf_thumbnail_viewer.js | 38 ++++++++++++++++++++++++++----------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js index 4b995313f..6463f44e1 100644 --- a/web/pdf_thumbnail_view.js +++ b/web/pdf_thumbnail_view.js @@ -130,12 +130,6 @@ class PDFThumbnailView { div.setAttribute('data-page-number', this.id); this.div = div; - if (id === 1) { - // Highlight the thumbnail of the first page when no page number is - // specified (or exists in cache) when the document is loaded. - div.classList.add('selected'); - } - let ring = document.createElement('div'); ring.className = 'thumbnailSelectionRing'; let borderAdjustment = 2 * THUMBNAIL_CANVAS_BORDER_WIDTH; diff --git a/web/pdf_thumbnail_viewer.js b/web/pdf_thumbnail_viewer.js index a84c72a48..14d29708f 100644 --- a/web/pdf_thumbnail_viewer.js +++ b/web/pdf_thumbnail_viewer.js @@ -19,6 +19,7 @@ import { import { PDFThumbnailView } from './pdf_thumbnail_view'; const THUMBNAIL_SCROLL_MARGIN = -19; +const THUMBNAIL_SELECTED_CLASS = 'selected'; /** * @typedef {Object} PDFThumbnailViewerOptions @@ -66,15 +67,23 @@ class PDFThumbnailViewer { return getVisibleElements(this.container, this._thumbnails); } - scrollThumbnailIntoView(page) { - let selected = document.querySelector('.thumbnail.selected'); - if (selected) { - selected.classList.remove('selected'); + scrollThumbnailIntoView(pageNumber) { + if (!this.pdfDocument) { + return; } - let thumbnail = document.querySelector( - 'div.thumbnail[data-page-number="' + page + '"]'); - if (thumbnail) { - thumbnail.classList.add('selected'); + const thumbnailView = this._thumbnails[pageNumber - 1]; + + if (!thumbnailView) { + console.error('scrollThumbnailIntoView: Invalid "pageNumber" parameter.'); + return; + } + + if (pageNumber !== this._currentPageNumber) { + const prevThumbnailView = this._thumbnails[this._currentPageNumber - 1]; + // Remove the highlight from the previous thumbnail... + prevThumbnailView.div.classList.remove(THUMBNAIL_SELECTED_CLASS); + // ... and add the highlight to the new thumbnail. + thumbnailView.div.classList.add(THUMBNAIL_SELECTED_CLASS); } let visibleThumbs = this._getVisibleThumbs(); let numVisibleThumbs = visibleThumbs.views.length; @@ -86,11 +95,11 @@ class PDFThumbnailViewer { let last = (numVisibleThumbs > 1 ? visibleThumbs.last.id : first); let shouldScroll = false; - if (page <= first || page >= last) { + if (pageNumber <= first || pageNumber >= last) { shouldScroll = true; } else { visibleThumbs.views.some(function(view) { - if (view.id !== page) { + if (view.id !== pageNumber) { return false; } shouldScroll = view.percent < 100; @@ -98,9 +107,11 @@ class PDFThumbnailViewer { }); } if (shouldScroll) { - scrollIntoView(thumbnail, { top: THUMBNAIL_SCROLL_MARGIN, }); + scrollIntoView(thumbnailView.div, { top: THUMBNAIL_SCROLL_MARGIN, }); } } + + this._currentPageNumber = pageNumber; } get pagesRotation() { @@ -133,6 +144,7 @@ class PDFThumbnailViewer { */ _resetView() { this._thumbnails = []; + this._currentPageNumber = 1; this._pageLabels = null; this._pagesRotation = 0; this._pagesRequests = []; @@ -167,6 +179,10 @@ class PDFThumbnailViewer { }); this._thumbnails.push(thumbnail); } + + // Ensure that the current thumbnail is always highlighted on load. + const thumbnailView = this._thumbnails[this._currentPageNumber - 1]; + thumbnailView.div.classList.add(THUMBNAIL_SELECTED_CLASS); }).catch((reason) => { console.error('Unable to initialize thumbnail viewer', reason); });