From 3bce14761acfd0bda8f1e0bae10f8f316df94dec Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Fri, 12 Sep 2014 14:48:44 -0500 Subject: [PATCH] Moves thumbs logic into PDFThumbnailViewer. --- web/thumbnail_view.js | 109 +++++++++++++++++++++++++++++++++++++++--- web/viewer.js | 72 +++++++--------------------- 2 files changed, 118 insertions(+), 63 deletions(-) diff --git a/web/thumbnail_view.js b/web/thumbnail_view.js index c48926698..d6721295e 100644 --- a/web/thumbnail_view.js +++ b/web/thumbnail_view.js @@ -14,16 +14,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* globals PDFView, mozL10n, RenderingStates */ +/* globals mozL10n, RenderingStates, THUMBNAIL_SCROLL_MARGIN, + watchScroll, getVisibleElements, scrollIntoView */ 'use strict'; -var ThumbnailView = function thumbnailView(container, id, defaultViewport) { +var ThumbnailView = function thumbnailView(container, id, defaultViewport, + linkService, renderingQueue) { var anchor = document.createElement('a'); - anchor.href = PDFView.getAnchorUrl('#page=' + id); + anchor.href = linkService.getAnchorUrl('#page=' + id); anchor.title = mozL10n.get('thumb_page_title', {page: id}, 'Page {{page}}'); anchor.onclick = function stopNavigation() { - PDFView.page = id; + linkService.page = id; return false; }; @@ -62,6 +64,7 @@ var ThumbnailView = function thumbnailView(container, id, defaultViewport) { this.hasImage = false; this.renderingState = RenderingStates.INITIAL; + this.renderingQueue = renderingQueue; this.setPdfPage = function thumbnailViewSetPdfPage(pdfPage) { this.pdfPage = pdfPage; @@ -125,7 +128,7 @@ var ThumbnailView = function thumbnailView(container, id, defaultViewport) { this.draw = function thumbnailViewDraw(callback) { if (!this.pdfPage) { - var promise = PDFView.getPage(this.id); + var promise = this.renderingQueue.getPage(this.id); promise.then(function(pdfPage) { this.setPdfPage(pdfPage); this.draw(callback); @@ -150,7 +153,7 @@ var ThumbnailView = function thumbnailView(container, id, defaultViewport) { canvasContext: ctx, viewport: drawViewport, continueCallback: function(cont) { - if (PDFView.highestPriorityPage !== 'thumbnail' + self.id) { + if (self.renderingQueue.highestPriorityPage !== 'thumbnail' + self.id) { self.renderingState = RenderingStates.PAUSED; self.resume = function() { self.renderingState = RenderingStates.RUNNING; @@ -187,7 +190,7 @@ var ThumbnailView = function thumbnailView(container, id, defaultViewport) { this.setImage = function thumbnailViewSetImage(img) { if (!this.pdfPage) { - var promise = PDFView.getPage(this.id); + var promise = this.renderingQueue.getPage(this.id); promise.then(function(pdfPage) { this.setPdfPage(pdfPage); this.setImage(img); @@ -232,3 +235,95 @@ var ThumbnailView = function thumbnailView(container, id, defaultViewport) { }; ThumbnailView.tempImageCache = null; + +var PDFThumbnailViewer = (function pdfThumbnailViewer() { + function PDFThumbnailViewer(options) { + this.container = options.container; + this.renderingQueue = options.renderingQueue; + this.linkService = options.linkService; + + this.scroll = watchScroll(this.container, this.scrollUpdated.bind(this)); + this.thumbnails = []; + this.currentPage = -1; + } + + PDFThumbnailViewer.prototype = { + scrollUpdated: function PDFThumbnailViewer_scrollUpdated() { + this.renderingQueue.renderHighestPriority(); + }, + + getVisibleThumbs: function PDFThumbnailViewer_getVisibleThumbs() { + return getVisibleElements(this.container, this.thumbnails); + }, + + updatePage: function (page) { + var selected = document.querySelector('.thumbnail.selected'); + if (selected) { + selected.classList.remove('selected'); + } + var thumbnail = document.getElementById('thumbnailContainer' + page); + thumbnail.classList.add('selected'); + var visibleThumbs = this.getVisibleThumbs(); + var numVisibleThumbs = visibleThumbs.views.length; + + // If the thumbnail isn't currently visible, scroll it into view. + if (numVisibleThumbs > 0) { + var first = visibleThumbs.first.id; + // Account for only one thumbnail being visible. + var last = (numVisibleThumbs > 1 ? visibleThumbs.last.id : first); + if (page <= first || page >= last) { + scrollIntoView(thumbnail, { top: THUMBNAIL_SCROLL_MARGIN }); + } + } + this.currentPage = page; + }, + + updateRotation: function (pageRotation) { + for (var i = 0, l = this.thumbnails.length; i < l; i++) { + var thumb = this.thumbnails[i]; + thumb.update(pageRotation); + } + }, + + cleanup: function PDFThumbnailViewer_cleanup() { + ThumbnailView.tempImageCache = null; + }, + + removeAllThumbnails: function PDFThumbnailViewer_cleanup() { + var thumbsView = this.container; + while (thumbsView.hasChildNodes()) { + thumbsView.removeChild(thumbsView.lastChild); + } + this.thumbnails = []; + }, + + addThumbnail: function PDFThumbnailViewer_addThumbnail(pageNum, viewport, + linkService) { + var thumbnail = new ThumbnailView(this.container, pageNum, viewport, + this.linkService, this.renderingQueue); + this.thumbnails.push(thumbnail); + return thumbnail; + }, + + ensureThumbnailVisible: + function PDFThumbnailViewer_ensureThumbnailVisible(page) { + // Ensure that the thumbnail of the current page is visible + // when switching from another view. + scrollIntoView(document.getElementById('thumbnailContainer' + page)); + }, + + forceRendering: function () { + var visibleThumbs = this.getVisibleThumbs(); + var thumbView = this.renderingQueue.getHighestPriority(visibleThumbs, + this.thumbnails, + this.scroll.down); + if (thumbView) { + this.renderingQueue.renderView(thumbView, 'thumbnail'); + return true; + } + return false; + } + }; + + return PDFThumbnailViewer; +})(); diff --git a/web/viewer.js b/web/viewer.js index 6cd58fb0c..ad9d90625 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -17,7 +17,7 @@ /* globals PDFJS, PDFBug, FirefoxCom, Stats, Cache, ProgressBar, DownloadManager, getFileName, scrollIntoView, getPDFFileNameFromURL, PDFHistory, Preferences, SidebarView, ViewHistory, PageView, - ThumbnailView, URL, noContextMenuHandler, SecondaryToolbar, + PDFThumbnailViewer, URL, noContextMenuHandler, SecondaryToolbar, PasswordPrompt, PresentationMode, HandTool, Promise, DocumentProperties, DocumentOutlineView, DocumentAttachmentsView, OverlayManager, PDFFindController, PDFFindBar, getVisibleElements, @@ -108,19 +108,17 @@ var currentPageNumber = 1; var PDFView = { pages: [], - thumbnails: [], currentScale: UNKNOWN_SCALE, currentScaleValue: null, initialBookmark: document.location.hash.substring(1), container: null, - thumbnailContainer: null, initialized: false, fellback: false, pdfDocument: null, sidebarOpen: false, printing: false, pageViewScroll: null, - thumbnailViewScroll: null, + pdfThumbnailViewer: null, pageRotation: 0, mouseScrollTimeStamp: 0, mouseScrollDelta: 0, @@ -137,12 +135,12 @@ var PDFView = { var container = this.container = document.getElementById('viewerContainer'); this.pageViewScroll = watchScroll(container, updateViewarea); - var thumbnailContainer = this.thumbnailContainer = - document.getElementById('thumbnailView'); - this.thumbnailViewScroll = watchScroll(thumbnailContainer, function () { - this.renderHighestPriority(); - }.bind(this)); - + var thumbnailContainer = document.getElementById('thumbnailView'); + this.pdfThumbnailViewer = new PDFThumbnailViewer({ + container: thumbnailContainer, + renderingQueue: this, + linkService: this + }); Preferences.initialize(); @@ -591,10 +589,7 @@ var PDFView = { this.pdfDocument.destroy(); this.pdfDocument = null; - var thumbsView = document.getElementById('thumbnailView'); - while (thumbsView.hasChildNodes()) { - thumbsView.removeChild(thumbsView.lastChild); - } + this.pdfThumbnailViewer.removeAllThumbnails(); var container = document.getElementById('viewer'); while (container.hasChildNodes()) { @@ -953,7 +948,6 @@ var PDFView = { var pages = this.pages = []; var pagesRefMap = this.pagesRefMap = {}; - var thumbnails = this.thumbnails = []; var resolvePagesPromise; var pagesPromise = new Promise(function (resolve) { @@ -963,7 +957,7 @@ var PDFView = { var firstPagePromise = pdfDocument.getPage(1); var container = document.getElementById('viewer'); - var thumbsView = document.getElementById('thumbnailView'); + var thumbsViewer = this.pdfThumbnailViewer; // Fetch a single page so we can get a viewport that will be the default // viewport for all pages @@ -974,11 +968,9 @@ var PDFView = { var pageView = new PageView(container, pageNum, scale, self.navigateTo.bind(self), viewportClone); - var thumbnailView = new ThumbnailView(thumbsView, pageNum, - viewportClone); + var thumbnailView = thumbsViewer.addThumbnail(pageNum, viewportClone); bindOnAfterDraw(pageView, thumbnailView); pages.push(pageView); - thumbnails.push(thumbnailView); } // Fetch all the pages since the viewport is needed before printing @@ -1239,12 +1231,7 @@ var PDFView = { } // No pages needed rendering so check thumbnails. if (this.sidebarOpen) { - var visibleThumbs = this.getVisibleThumbs(); - var thumbView = this.getHighestPriority(visibleThumbs, - this.thumbnails, - this.thumbnailViewScroll.down); - if (thumbView) { - this.renderView(thumbView, 'thumbnail'); + if (this.pdfThumbnailViewer.forceRendering()) { return; } } @@ -1268,7 +1255,7 @@ var PDFView = { } this.pdfDocument.cleanup(); - ThumbnailView.tempImageCache = null; + this.pdfThumbnailViewer.cleanup(); }, getHighestPriority: function pdfViewGetHighestPriority(visible, views, @@ -1424,10 +1411,7 @@ var PDFView = { PDFView.renderHighestPriority(); if (wasAnotherViewVisible) { - // Ensure that the thumbnail of the current page is visible - // when switching from another view. - scrollIntoView(document.getElementById('thumbnailContainer' + - this.page)); + this.pdfThumbnailViewer.ensureThumbnailVisible(this.page); } break; @@ -1472,10 +1456,6 @@ var PDFView = { } }, - getVisibleThumbs: function pdfViewGetVisibleThumbs() { - return getVisibleElements(this.thumbnailContainer, this.thumbnails); - }, - // Helper function to parse query string (e.g. ?param1=value&parm2=...). parseQueryString: function pdfViewParseQueryString(query) { var parts = query.split('&'); @@ -1552,10 +1532,7 @@ var PDFView = { page.update(page.scale, this.pageRotation); } - for (i = 0, l = this.thumbnails.length; i < l; i++) { - var thumb = this.thumbnails[i]; - thumb.update(this.pageRotation); - } + this.pdfThumbnailViewer.updateRotation(this.pageRotation); this.setScale(this.currentScaleValue, true, true); @@ -2131,24 +2108,7 @@ window.addEventListener('pagechange', function pagechange(evt) { var page = evt.pageNumber; if (PDFView.previousPageNumber !== page) { document.getElementById('pageNumber').value = page; - var selected = document.querySelector('.thumbnail.selected'); - if (selected) { - selected.classList.remove('selected'); - } - var thumbnail = document.getElementById('thumbnailContainer' + page); - thumbnail.classList.add('selected'); - var visibleThumbs = PDFView.getVisibleThumbs(); - var numVisibleThumbs = visibleThumbs.views.length; - - // If the thumbnail isn't currently visible, scroll it into view. - if (numVisibleThumbs > 0) { - var first = visibleThumbs.first.id; - // Account for only one thumbnail being visible. - var last = (numVisibleThumbs > 1 ? visibleThumbs.last.id : first); - if (page <= first || page >= last) { - scrollIntoView(thumbnail, { top: THUMBNAIL_SCROLL_MARGIN }); - } - } + PDFView.pdfThumbnailViewer.updatePage(page); } var numPages = PDFView.pages.length;