From c55dcf19a02b7fc718c25ddcef2139c1469a5a17 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sat, 24 Jan 2015 13:51:55 +0100 Subject: [PATCH 1/7] Move PDFThumbnailViewer to its own file --- web/pdf_thumbnail_viewer.js | 180 ++++++++++++++++++++++++++++++++++++ web/thumbnail_view.js | 160 +------------------------------- web/viewer.html | 1 + web/viewer.js | 2 +- 4 files changed, 183 insertions(+), 160 deletions(-) create mode 100644 web/pdf_thumbnail_viewer.js diff --git a/web/pdf_thumbnail_viewer.js b/web/pdf_thumbnail_viewer.js new file mode 100644 index 000000000..570fbb3b8 --- /dev/null +++ b/web/pdf_thumbnail_viewer.js @@ -0,0 +1,180 @@ +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ +/* Copyright 2012 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* globals watchScroll, getVisibleElements, scrollIntoView, ThumbnailView, + Promise */ + +'use strict'; + +var THUMBNAIL_SCROLL_MARGIN = -19; + +//#include thumbnail_view.js + +/** + * @typedef {Object} PDFThumbnailViewerOptions + * @property {HTMLDivElement} container - The container for the thumbs elements. + * @property {IPDFLinkService} linkService - The navigation/linking service. + * @property {PDFRenderingQueue} renderingQueue - The rendering queue object. + */ + +/** + * Simple viewer control to display thumbs for pages. + * @class + */ +var PDFThumbnailViewer = (function pdfThumbnailViewer() { + /** + * @constructs + * @param {PDFThumbnailViewerOptions} options + */ + 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._resetView(); + } + + PDFThumbnailViewer.prototype = { + _scrollUpdated: function PDFThumbnailViewer_scrollUpdated() { + this.renderingQueue.renderHighestPriority(); + }, + + getThumbnail: function PDFThumbnailViewer_getThumbnail(index) { + return this.thumbnails[index]; + }, + + _getVisibleThumbs: function PDFThumbnailViewer_getVisibleThumbs() { + return getVisibleElements(this.container, this.thumbnails); + }, + + scrollThumbnailIntoView: 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 }); + } + } + }, + + get pagesRotation() { + return this._pagesRotation; + }, + + set pagesRotation(rotation) { + this._pagesRotation = rotation; + for (var i = 0, l = this.thumbnails.length; i < l; i++) { + var thumb = this.thumbnails[i]; + thumb.update(rotation); + } + }, + + cleanup: function PDFThumbnailViewer_cleanup() { + ThumbnailView.tempImageCache = null; + }, + + _resetView: function () { + this.thumbnails = []; + this._pagesRotation = 0; + this._pagesRequests = []; + }, + + setDocument: function (pdfDocument) { + if (this.pdfDocument) { + // cleanup of the elements and views + var thumbsView = this.container; + while (thumbsView.hasChildNodes()) { + thumbsView.removeChild(thumbsView.lastChild); + } + this._resetView(); + } + + this.pdfDocument = pdfDocument; + if (!pdfDocument) { + return Promise.resolve(); + } + + return pdfDocument.getPage(1).then(function (firstPage) { + var pagesCount = pdfDocument.numPages; + var viewport = firstPage.getViewport(1.0); + for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) { + var thumbnail = new ThumbnailView(this.container, pageNum, + viewport.clone(), this.linkService, + this.renderingQueue); + this.thumbnails.push(thumbnail); + } + }.bind(this)); + }, + + /** + * @param {PDFPageView} pageView + * @returns {PDFPage} + * @private + */ + _ensurePdfPageLoaded: function (thumbView) { + if (thumbView.pdfPage) { + return Promise.resolve(thumbView.pdfPage); + } + var pageNumber = thumbView.id; + if (this._pagesRequests[pageNumber]) { + return this._pagesRequests[pageNumber]; + } + var promise = this.pdfDocument.getPage(pageNumber).then( + function (pdfPage) { + thumbView.setPdfPage(pdfPage); + this._pagesRequests[pageNumber] = null; + return pdfPage; + }.bind(this)); + this._pagesRequests[pageNumber] = promise; + return promise; + }, + + 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._ensurePdfPageLoaded(thumbView).then(function () { + this.renderingQueue.renderView(thumbView); + }.bind(this)); + return true; + } + return false; + } + }; + + return PDFThumbnailViewer; +})(); diff --git a/web/thumbnail_view.js b/web/thumbnail_view.js index 9dacb68f1..ee304a8a5 100644 --- a/web/thumbnail_view.js +++ b/web/thumbnail_view.js @@ -14,12 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* globals mozL10n, RenderingStates, Promise, scrollIntoView, - watchScroll, getVisibleElements */ +/* globals mozL10n, RenderingStates, Promise */ 'use strict'; -var THUMBNAIL_SCROLL_MARGIN = -19; var THUMBNAIL_CANVAS_BORDER_WIDTH = 1; /** @@ -252,159 +250,3 @@ var ThumbnailView = function thumbnailView(container, id, defaultViewport, }; ThumbnailView.tempImageCache = null; - -/** - * @typedef {Object} PDFThumbnailViewerOptions - * @property {HTMLDivElement} container - The container for the thumbs elements. - * @property {IPDFLinkService} linkService - The navigation/linking service. - * @property {PDFRenderingQueue} renderingQueue - The rendering queue object. - */ - -/** - * Simple viewer control to display thumbs for pages. - * @class - */ -var PDFThumbnailViewer = (function pdfThumbnailViewer() { - /** - * @constructs - * @param {PDFThumbnailViewerOptions} options - */ - 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._resetView(); - } - - PDFThumbnailViewer.prototype = { - _scrollUpdated: function PDFThumbnailViewer_scrollUpdated() { - this.renderingQueue.renderHighestPriority(); - }, - - getThumbnail: function PDFThumbnailViewer_getThumbnail(index) { - return this.thumbnails[index]; - }, - - _getVisibleThumbs: function PDFThumbnailViewer_getVisibleThumbs() { - return getVisibleElements(this.container, this.thumbnails); - }, - - scrollThumbnailIntoView: 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 }); - } - } - }, - - get pagesRotation() { - return this._pagesRotation; - }, - - set pagesRotation(rotation) { - this._pagesRotation = rotation; - for (var i = 0, l = this.thumbnails.length; i < l; i++) { - var thumb = this.thumbnails[i]; - thumb.update(rotation); - } - }, - - cleanup: function PDFThumbnailViewer_cleanup() { - ThumbnailView.tempImageCache = null; - }, - - _resetView: function () { - this.thumbnails = []; - this._pagesRotation = 0; - this._pagesRequests = []; - }, - - setDocument: function (pdfDocument) { - if (this.pdfDocument) { - // cleanup of the elements and views - var thumbsView = this.container; - while (thumbsView.hasChildNodes()) { - thumbsView.removeChild(thumbsView.lastChild); - } - this._resetView(); - } - - this.pdfDocument = pdfDocument; - if (!pdfDocument) { - return Promise.resolve(); - } - - return pdfDocument.getPage(1).then(function (firstPage) { - var pagesCount = pdfDocument.numPages; - var viewport = firstPage.getViewport(1.0); - for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) { - var thumbnail = new ThumbnailView(this.container, pageNum, - viewport.clone(), this.linkService, - this.renderingQueue); - this.thumbnails.push(thumbnail); - } - }.bind(this)); - }, - - /** - * @param {PDFPageView} pageView - * @returns {PDFPage} - * @private - */ - _ensurePdfPageLoaded: function (thumbView) { - if (thumbView.pdfPage) { - return Promise.resolve(thumbView.pdfPage); - } - var pageNumber = thumbView.id; - if (this._pagesRequests[pageNumber]) { - return this._pagesRequests[pageNumber]; - } - var promise = this.pdfDocument.getPage(pageNumber).then( - function (pdfPage) { - thumbView.setPdfPage(pdfPage); - this._pagesRequests[pageNumber] = null; - return pdfPage; - }.bind(this)); - this._pagesRequests[pageNumber] = promise; - return promise; - }, - - 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._ensurePdfPageLoaded(thumbView).then(function () { - this.renderingQueue.renderView(thumbView); - }.bind(this)); - return true; - } - return false; - } - }; - - return PDFThumbnailViewer; -})(); diff --git a/web/viewer.html b/web/viewer.html index d6588d940..894058955 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -74,6 +74,7 @@ http://sourceforge.net/adobe/cmap/wiki/License/ + diff --git a/web/viewer.js b/web/viewer.js index 806c9f065..d47962d01 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -85,6 +85,7 @@ var mozL10n = document.mozL10n || document.webL10n; //#include password_prompt.js //#include document_properties.js //#include pdf_viewer.js +//#include pdf_thumbnail_viewer.js var PDFViewerApplication = { initialBookmark: document.location.hash.substring(1), @@ -1389,7 +1390,6 @@ var PDFViewerApplication = { window.PDFView = PDFViewerApplication; // obsolete name, using it as an alias //#endif -//#include thumbnail_view.js //#include document_outline_view.js //#include document_attachments_view.js From dfa993d13d03d71dc645c96ffafbbacbe31144c1 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sat, 24 Jan 2015 15:40:18 +0100 Subject: [PATCH 2/7] Fix function names in PDFThumbnailViewer Also updates a couple of the JSDoc comments. --- web/pdf_thumbnail_viewer.js | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/web/pdf_thumbnail_viewer.js b/web/pdf_thumbnail_viewer.js index 570fbb3b8..d926028ec 100644 --- a/web/pdf_thumbnail_viewer.js +++ b/web/pdf_thumbnail_viewer.js @@ -25,18 +25,20 @@ var THUMBNAIL_SCROLL_MARGIN = -19; /** * @typedef {Object} PDFThumbnailViewerOptions - * @property {HTMLDivElement} container - The container for the thumbs elements. + * @property {HTMLDivElement} container - The container for the thumbnail + * elements. * @property {IPDFLinkService} linkService - The navigation/linking service. * @property {PDFRenderingQueue} renderingQueue - The rendering queue object. */ /** - * Simple viewer control to display thumbs for pages. + * Simple viewer control to display thumbnails for pages. * @class + * @implements {IRenderableView} */ -var PDFThumbnailViewer = (function pdfThumbnailViewer() { +var PDFThumbnailViewer = (function PDFThumbnailViewerClosure() { /** - * @constructs + * @constructs PDFThumbnailViewer * @param {PDFThumbnailViewerOptions} options */ function PDFThumbnailViewer(options) { @@ -49,6 +51,9 @@ var PDFThumbnailViewer = (function pdfThumbnailViewer() { } PDFThumbnailViewer.prototype = { + /** + * @private + */ _scrollUpdated: function PDFThumbnailViewer_scrollUpdated() { this.renderingQueue.renderHighestPriority(); }, @@ -57,11 +62,15 @@ var PDFThumbnailViewer = (function pdfThumbnailViewer() { return this.thumbnails[index]; }, + /** + * @private + */ _getVisibleThumbs: function PDFThumbnailViewer_getVisibleThumbs() { return getVisibleElements(this.container, this.thumbnails); }, - scrollThumbnailIntoView: function (page) { + scrollThumbnailIntoView: + function PDFThumbnailViewer_scrollThumbnailIntoView(page) { var selected = document.querySelector('.thumbnail.selected'); if (selected) { selected.classList.remove('selected'); @@ -98,13 +107,16 @@ var PDFThumbnailViewer = (function pdfThumbnailViewer() { ThumbnailView.tempImageCache = null; }, - _resetView: function () { + /** + * @private + */ + _resetView: function PDFThumbnailViewer_resetView() { this.thumbnails = []; this._pagesRotation = 0; this._pagesRequests = []; }, - setDocument: function (pdfDocument) { + setDocument: function PDFThumbnailViewer_setDocument(pdfDocument) { if (this.pdfDocument) { // cleanup of the elements and views var thumbsView = this.container; @@ -136,7 +148,8 @@ var PDFThumbnailViewer = (function pdfThumbnailViewer() { * @returns {PDFPage} * @private */ - _ensurePdfPageLoaded: function (thumbView) { + _ensurePdfPageLoaded: + function PDFThumbnailViewer_ensurePdfPageLoaded(thumbView) { if (thumbView.pdfPage) { return Promise.resolve(thumbView.pdfPage); } From 64ba38008f00a4990e691ed8ba7d4f4f66edd5d8 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sat, 24 Jan 2015 15:46:10 +0100 Subject: [PATCH 3/7] Rename the thumbnail_view.js file --- web/{thumbnail_view.js => pdf_thumbnail_view.js} | 0 web/pdf_thumbnail_viewer.js | 2 +- web/viewer.html | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename web/{thumbnail_view.js => pdf_thumbnail_view.js} (100%) diff --git a/web/thumbnail_view.js b/web/pdf_thumbnail_view.js similarity index 100% rename from web/thumbnail_view.js rename to web/pdf_thumbnail_view.js diff --git a/web/pdf_thumbnail_viewer.js b/web/pdf_thumbnail_viewer.js index d926028ec..e2f94198e 100644 --- a/web/pdf_thumbnail_viewer.js +++ b/web/pdf_thumbnail_viewer.js @@ -21,7 +21,7 @@ var THUMBNAIL_SCROLL_MARGIN = -19; -//#include thumbnail_view.js +//#include pdf_thumbnail_view.js /** * @typedef {Object} PDFThumbnailViewerOptions diff --git a/web/viewer.html b/web/viewer.html index 894058955..1aa78dda1 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -73,7 +73,7 @@ http://sourceforge.net/adobe/cmap/wiki/License/ - + From 7f8f4045366a030c36dfbc2f488bf25a50e72040 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sat, 24 Jan 2015 16:27:31 +0100 Subject: [PATCH 4/7] Rename ThumbnailView to PDFThumbnailView and refactor it to be more class-like --- web/pdf_thumbnail_view.js | 428 +++++++++++++++++++----------------- web/pdf_thumbnail_viewer.js | 14 +- 2 files changed, 234 insertions(+), 208 deletions(-) diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js index ee304a8a5..bf8c2d11a 100644 --- a/web/pdf_thumbnail_view.js +++ b/web/pdf_thumbnail_view.js @@ -21,175 +21,24 @@ var THUMBNAIL_CANVAS_BORDER_WIDTH = 1; /** - * @constructor - * @param container - * @param id - * @param defaultViewport - * @param linkService - * @param renderingQueue - * + * @typedef {Object} PDFThumbnailViewOptions + * @property {HTMLDivElement} container - The viewer element. + * @property {number} id - The thumbnail's unique ID (normally its number). + * @property {PageViewport} defaultViewport - The page viewport. + * @property {IPDFLinkService} linkService - The navigation/linking service. + * @property {PDFRenderingQueue} renderingQueue - The rendering queue object. + */ + +/** + * @class * @implements {IRenderableView} */ -var ThumbnailView = function thumbnailView(container, id, defaultViewport, - linkService, renderingQueue) { - var anchor = document.createElement('a'); - anchor.href = linkService.getAnchorUrl('#page=' + id); - anchor.title = mozL10n.get('thumb_page_title', {page: id}, 'Page {{page}}'); - anchor.onclick = function stopNavigation() { - linkService.page = id; - return false; - }; - - this.pdfPage = undefined; - this.viewport = defaultViewport; - this.pdfPageRotate = defaultViewport.rotation; - - this.rotation = 0; - this.pageWidth = this.viewport.width; - this.pageHeight = this.viewport.height; - this.pageRatio = this.pageWidth / this.pageHeight; - this.id = id; - this.renderingId = 'thumbnail' + id; - - this.canvasWidth = 98; - this.canvasHeight = (this.canvasWidth / this.pageRatio) | 0; - this.scale = this.canvasWidth / this.pageWidth; - - var div = this.el = document.createElement('div'); - div.id = 'thumbnailContainer' + id; - div.className = 'thumbnail'; - - 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'); - } - - var ring = document.createElement('div'); - ring.className = 'thumbnailSelectionRing'; - ring.style.width = this.canvasWidth + 2 * THUMBNAIL_CANVAS_BORDER_WIDTH + - 'px'; - ring.style.height = this.canvasHeight + 2 * THUMBNAIL_CANVAS_BORDER_WIDTH + - 'px'; - - div.appendChild(ring); - anchor.appendChild(div); - container.appendChild(anchor); - - this.hasImage = false; - this.renderingState = RenderingStates.INITIAL; - this.renderingQueue = renderingQueue; - - this.setPdfPage = function thumbnailViewSetPdfPage(pdfPage) { - this.pdfPage = pdfPage; - this.pdfPageRotate = pdfPage.rotate; - var totalRotation = (this.rotation + this.pdfPageRotate) % 360; - this.viewport = pdfPage.getViewport(1, totalRotation); - this.update(); - }; - - this.update = function thumbnailViewUpdate(rotation) { - if (rotation !== undefined) { - this.rotation = rotation; - } - var totalRotation = (this.rotation + this.pdfPageRotate) % 360; - this.viewport = this.viewport.clone({ - scale: 1, - rotation: totalRotation - }); - this.pageWidth = this.viewport.width; - this.pageHeight = this.viewport.height; - this.pageRatio = this.pageWidth / this.pageHeight; - - this.canvasHeight = (this.canvasWidth / this.pageRatio) | 0; - this.scale = (this.canvasWidth / this.pageWidth); - - div.removeAttribute('data-loaded'); - ring.textContent = ''; - ring.style.width = this.canvasWidth + 2 * THUMBNAIL_CANVAS_BORDER_WIDTH + - 'px'; - ring.style.height = this.canvasHeight + 2 * THUMBNAIL_CANVAS_BORDER_WIDTH + - 'px'; - - this.hasImage = false; - this.renderingState = RenderingStates.INITIAL; - this.resume = null; - }; - - this.getPageDrawContext = function thumbnailViewGetPageDrawContext() { - var canvas = document.createElement('canvas'); - canvas.id = 'thumbnail' + id; - - canvas.width = this.canvasWidth; - canvas.height = this.canvasHeight; - canvas.className = 'thumbnailImage'; - canvas.setAttribute('aria-label', mozL10n.get('thumb_page_canvas', - {page: id}, 'Thumbnail of Page {{page}}')); - - div.setAttribute('data-loaded', true); - - ring.appendChild(canvas); - - return canvas.getContext('2d'); - }; - - this.drawingRequired = function thumbnailViewDrawingRequired() { - return !this.hasImage; - }; - - this.draw = function thumbnailViewDraw() { - if (this.renderingState !== RenderingStates.INITIAL) { - console.error('Must be in new state before drawing'); - } - - this.renderingState = RenderingStates.RUNNING; - if (this.hasImage) { - return Promise.resolve(undefined); - } - - var resolveRenderPromise, rejectRenderPromise; - var promise = new Promise(function (resolve, reject) { - resolveRenderPromise = resolve; - rejectRenderPromise = reject; - }); - - var self = this; - var ctx = this.getPageDrawContext(); - var drawViewport = this.viewport.clone({ scale: this.scale }); - var renderContext = { - canvasContext: ctx, - viewport: drawViewport, - continueCallback: function(cont) { - if (!self.renderingQueue.isHighestPriority(self)) { - self.renderingState = RenderingStates.PAUSED; - self.resume = function() { - self.renderingState = RenderingStates.RUNNING; - cont(); - }; - return; - } - cont(); - } - }; - this.pdfPage.render(renderContext).promise.then( - function pdfPageRenderCallback() { - self.renderingState = RenderingStates.FINISHED; - resolveRenderPromise(undefined); - }, - function pdfPageRenderError(error) { - self.renderingState = RenderingStates.FINISHED; - rejectRenderPromise(error); - } - ); - this.hasImage = true; - return promise; - }; - +var PDFThumbnailView = (function PDFThumbnailViewClosure() { function getTempCanvas(width, height) { - var tempCanvas = ThumbnailView.tempImageCache; + var tempCanvas = PDFThumbnailView.tempImageCache; if (!tempCanvas) { tempCanvas = document.createElement('canvas'); - ThumbnailView.tempImageCache = tempCanvas; + PDFThumbnailView.tempImageCache = tempCanvas; } tempCanvas.width = width; tempCanvas.height = height; @@ -205,48 +54,221 @@ var ThumbnailView = function thumbnailView(container, id, defaultViewport, return tempCanvas; } - this.setImage = function thumbnailViewSetImage(pageView) { - var img = pageView.canvas; - if (this.hasImage || !img) { - return; - } - if (!this.pdfPage) { - this.setPdfPage(pageView.pdfPage); - } - this.renderingState = RenderingStates.FINISHED; - var ctx = this.getPageDrawContext(); - var canvas = ctx.canvas; + /** + * @constructs PDFThumbnailView + * @param {PDFThumbnailViewOptions} options + */ + function PDFThumbnailView(options) { + var container = options.container; + var id = options.id; + var defaultViewport = options.defaultViewport; + var linkService = options.linkService; + var renderingQueue = options.renderingQueue; - if (img.width <= 2 * canvas.width) { - ctx.drawImage(img, 0, 0, img.width, img.height, - 0, 0, canvas.width, canvas.height); - } else { - // drawImage does an awful job of rescaling the image, doing it gradually - var MAX_NUM_SCALING_STEPS = 3; - var reducedWidth = canvas.width << MAX_NUM_SCALING_STEPS; - var reducedHeight = canvas.height << MAX_NUM_SCALING_STEPS; - var reducedImage = getTempCanvas(reducedWidth, reducedHeight); - var reducedImageCtx = reducedImage.getContext('2d'); + var anchor = document.createElement('a'); + anchor.href = linkService.getAnchorUrl('#page=' + id); + anchor.title = mozL10n.get('thumb_page_title', {page: id}, 'Page {{page}}'); + anchor.onclick = function stopNavigation() { + linkService.page = id; + return false; + }; - while (reducedWidth > img.width || reducedHeight > img.height) { - reducedWidth >>= 1; - reducedHeight >>= 1; + this.pdfPage = undefined; + this.viewport = defaultViewport; + this.pdfPageRotate = defaultViewport.rotation; + + this.rotation = 0; + this.pageWidth = this.viewport.width; + this.pageHeight = this.viewport.height; + this.pageRatio = this.pageWidth / this.pageHeight; + this.id = id; + this.renderingId = 'thumbnail' + id; + + this.canvasWidth = 98; + this.canvasHeight = (this.canvasWidth / this.pageRatio) | 0; + this.scale = this.canvasWidth / this.pageWidth; + + var div = this.el = document.createElement('div'); + div.id = 'thumbnailContainer' + id; + div.className = 'thumbnail'; + 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'); + } + + var ring = document.createElement('div'); + ring.className = 'thumbnailSelectionRing'; + ring.style.width = + this.canvasWidth + 2 * THUMBNAIL_CANVAS_BORDER_WIDTH + 'px'; + ring.style.height = + this.canvasHeight + 2 * THUMBNAIL_CANVAS_BORDER_WIDTH + 'px'; + this.ring = ring; + + div.appendChild(ring); + anchor.appendChild(div); + container.appendChild(anchor); + + this.hasImage = false; + this.renderingState = RenderingStates.INITIAL; + this.renderingQueue = renderingQueue; + } + + PDFThumbnailView.prototype = { + setPdfPage: function PDFThumbnailView_setPdfPage(pdfPage) { + this.pdfPage = pdfPage; + this.pdfPageRotate = pdfPage.rotate; + var totalRotation = (this.rotation + this.pdfPageRotate) % 360; + this.viewport = pdfPage.getViewport(1, totalRotation); + this.update(); + }, + + update: function PDFThumbnailView_update(rotation) { + if (rotation !== undefined) { + this.rotation = rotation; } - reducedImageCtx.drawImage(img, 0, 0, img.width, img.height, - 0, 0, reducedWidth, reducedHeight); - while (reducedWidth > 2 * canvas.width) { - reducedImageCtx.drawImage(reducedImage, - 0, 0, reducedWidth, reducedHeight, - 0, 0, reducedWidth >> 1, reducedHeight >> 1); - reducedWidth >>= 1; - reducedHeight >>= 1; - } - ctx.drawImage(reducedImage, 0, 0, reducedWidth, reducedHeight, - 0, 0, canvas.width, canvas.height); - } + var totalRotation = (this.rotation + this.pdfPageRotate) % 360; + this.viewport = this.viewport.clone({ + scale: 1, + rotation: totalRotation + }); + this.pageWidth = this.viewport.width; + this.pageHeight = this.viewport.height; + this.pageRatio = this.pageWidth / this.pageHeight; - this.hasImage = true; + this.canvasHeight = (this.canvasWidth / this.pageRatio) | 0; + this.scale = (this.canvasWidth / this.pageWidth); + + this.div.removeAttribute('data-loaded'); + this.ring.textContent = ''; + this.ring.style.width = + this.canvasWidth + 2 * THUMBNAIL_CANVAS_BORDER_WIDTH + 'px'; + this.ring.style.height = + this.canvasHeight + 2 * THUMBNAIL_CANVAS_BORDER_WIDTH + 'px'; + + this.hasImage = false; + this.renderingState = RenderingStates.INITIAL; + this.resume = null; + }, + + getPageDrawContext: function PDFThumbnailView_getPageDrawContext() { + var canvas = document.createElement('canvas'); + canvas.id = 'thumbnail' + this.id; + + canvas.width = this.canvasWidth; + canvas.height = this.canvasHeight; + canvas.className = 'thumbnailImage'; + canvas.setAttribute('aria-label', mozL10n.get('thumb_page_canvas', + {page: this.id}, 'Thumbnail of Page {{page}}')); + + this.div.setAttribute('data-loaded', true); + + this.ring.appendChild(canvas); + + return canvas.getContext('2d'); + }, + + drawingRequired: function PDFThumbnailView_drawingRequired() { + return !this.hasImage; + }, + + draw: function PDFThumbnailView_draw() { + if (this.renderingState !== RenderingStates.INITIAL) { + console.error('Must be in new state before drawing'); + } + + this.renderingState = RenderingStates.RUNNING; + if (this.hasImage) { + return Promise.resolve(undefined); + } + + var resolveRenderPromise, rejectRenderPromise; + var promise = new Promise(function (resolve, reject) { + resolveRenderPromise = resolve; + rejectRenderPromise = reject; + }); + + var self = this; + var ctx = this.getPageDrawContext(); + var drawViewport = this.viewport.clone({ scale: this.scale }); + var renderContext = { + canvasContext: ctx, + viewport: drawViewport, + continueCallback: function(cont) { + if (!self.renderingQueue.isHighestPriority(self)) { + self.renderingState = RenderingStates.PAUSED; + self.resume = function() { + self.renderingState = RenderingStates.RUNNING; + cont(); + }; + return; + } + cont(); + } + }; + this.pdfPage.render(renderContext).promise.then( + function pdfPageRenderCallback() { + self.renderingState = RenderingStates.FINISHED; + resolveRenderPromise(undefined); + }, + function pdfPageRenderError(error) { + self.renderingState = RenderingStates.FINISHED; + rejectRenderPromise(error); + } + ); + this.hasImage = true; + return promise; + }, + + setImage: function PDFThumbnailView_setImage(pageView) { + var img = pageView.canvas; + if (this.hasImage || !img) { + return; + } + if (!this.pdfPage) { + this.setPdfPage(pageView.pdfPage); + } + this.renderingState = RenderingStates.FINISHED; + var ctx = this.getPageDrawContext(); + var canvas = ctx.canvas; + + if (img.width <= 2 * canvas.width) { + ctx.drawImage(img, 0, 0, img.width, img.height, + 0, 0, canvas.width, canvas.height); + } else { + // drawImage does an awful job of rescaling the image, + // doing it gradually. + var MAX_NUM_SCALING_STEPS = 3; + var reducedWidth = canvas.width << MAX_NUM_SCALING_STEPS; + var reducedHeight = canvas.height << MAX_NUM_SCALING_STEPS; + var reducedImage = getTempCanvas(reducedWidth, reducedHeight); + var reducedImageCtx = reducedImage.getContext('2d'); + + while (reducedWidth > img.width || reducedHeight > img.height) { + reducedWidth >>= 1; + reducedHeight >>= 1; + } + reducedImageCtx.drawImage(img, 0, 0, img.width, img.height, + 0, 0, reducedWidth, reducedHeight); + while (reducedWidth > 2 * canvas.width) { + reducedImageCtx.drawImage(reducedImage, + 0, 0, reducedWidth, reducedHeight, + 0, 0, + reducedWidth >> 1, reducedHeight >> 1); + reducedWidth >>= 1; + reducedHeight >>= 1; + } + ctx.drawImage(reducedImage, 0, 0, reducedWidth, reducedHeight, + 0, 0, canvas.width, canvas.height); + } + + this.hasImage = true; + } }; -}; -ThumbnailView.tempImageCache = null; + return PDFThumbnailView; +})(); + +PDFThumbnailView.tempImageCache = null; diff --git a/web/pdf_thumbnail_viewer.js b/web/pdf_thumbnail_viewer.js index e2f94198e..db464fc3b 100644 --- a/web/pdf_thumbnail_viewer.js +++ b/web/pdf_thumbnail_viewer.js @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* globals watchScroll, getVisibleElements, scrollIntoView, ThumbnailView, +/* globals watchScroll, getVisibleElements, scrollIntoView, PDFThumbnailView, Promise */ 'use strict'; @@ -104,7 +104,7 @@ var PDFThumbnailViewer = (function PDFThumbnailViewerClosure() { }, cleanup: function PDFThumbnailViewer_cleanup() { - ThumbnailView.tempImageCache = null; + PDFThumbnailView.tempImageCache = null; }, /** @@ -135,9 +135,13 @@ var PDFThumbnailViewer = (function PDFThumbnailViewerClosure() { var pagesCount = pdfDocument.numPages; var viewport = firstPage.getViewport(1.0); for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) { - var thumbnail = new ThumbnailView(this.container, pageNum, - viewport.clone(), this.linkService, - this.renderingQueue); + var thumbnail = new PDFThumbnailView({ + container: this.container, + id: pageNum, + defaultViewport: viewport.clone(), + linkService: this.linkService, + renderingQueue: this.renderingQueue + }); this.thumbnails.push(thumbnail); } }.bind(this)); From 878aa76c15ccd54c40adcbf9e59807244fceda69 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sun, 25 Jan 2015 13:27:11 +0100 Subject: [PATCH 5/7] Refactor PDFThumbnailView to look more similar to PDFPageView This includes an optimization to zero the height and width of existing thumbnail canvases, when they are removed and recreated during rotation of the document. (Credit goes to nnethercote, who initially found this in PR 4920.) --- web/pdf_thumbnail_view.js | 187 ++++++++++++++++++++---------------- web/pdf_thumbnail_viewer.js | 7 ++ 2 files changed, 110 insertions(+), 84 deletions(-) diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js index bf8c2d11a..26a2a52ca 100644 --- a/web/pdf_thumbnail_view.js +++ b/web/pdf_thumbnail_view.js @@ -18,7 +18,8 @@ 'use strict'; -var THUMBNAIL_CANVAS_BORDER_WIDTH = 1; +var THUMBNAIL_WIDTH = 98; // px +var THUMBNAIL_CANVAS_BORDER_WIDTH = 1; // px /** * @typedef {Object} PDFThumbnailViewOptions @@ -43,9 +44,8 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() { tempCanvas.width = width; tempCanvas.height = height; - // Since this is a temporary canvas, we need to fill - // the canvas with a white background ourselves. - // |getPageDrawContext| uses CSS rules for this. + // Since this is a temporary canvas, we need to fill the canvas with a white + // background ourselves. |_getPageDrawContext| uses CSS rules for this. var ctx = tempCanvas.getContext('2d'); ctx.save(); ctx.fillStyle = 'rgb(255, 255, 255)'; @@ -65,6 +65,29 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() { var linkService = options.linkService; var renderingQueue = options.renderingQueue; + this.id = id; + this.renderingId = 'thumbnail' + id; + + this.pdfPage = null; + this.rotation = 0; + this.viewport = defaultViewport; + this.pdfPageRotate = defaultViewport.rotation; + + this.linkService = linkService; + this.renderingQueue = renderingQueue; + + this.hasImage = false; + this.resume = null; + this.renderingState = RenderingStates.INITIAL; + + this.pageWidth = this.viewport.width; + this.pageHeight = this.viewport.height; + this.pageRatio = this.pageWidth / this.pageHeight; + + this.canvasWidth = THUMBNAIL_WIDTH; + this.canvasHeight = (this.canvasWidth / this.pageRatio) | 0; + this.scale = this.canvasWidth / this.pageWidth; + var anchor = document.createElement('a'); anchor.href = linkService.getAnchorUrl('#page=' + id); anchor.title = mozL10n.get('thumb_page_title', {page: id}, 'Page {{page}}'); @@ -73,24 +96,10 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() { return false; }; - this.pdfPage = undefined; - this.viewport = defaultViewport; - this.pdfPageRotate = defaultViewport.rotation; - - this.rotation = 0; - this.pageWidth = this.viewport.width; - this.pageHeight = this.viewport.height; - this.pageRatio = this.pageWidth / this.pageHeight; - this.id = id; - this.renderingId = 'thumbnail' + id; - - this.canvasWidth = 98; - this.canvasHeight = (this.canvasWidth / this.pageRatio) | 0; - this.scale = this.canvasWidth / this.pageWidth; - - var div = this.el = document.createElement('div'); + var div = document.createElement('div'); div.id = 'thumbnailContainer' + id; div.className = 'thumbnail'; + this.el = div; // TODO: replace 'el' property usage. this.div = div; if (id === 1) { @@ -101,19 +110,14 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() { var ring = document.createElement('div'); ring.className = 'thumbnailSelectionRing'; - ring.style.width = - this.canvasWidth + 2 * THUMBNAIL_CANVAS_BORDER_WIDTH + 'px'; - ring.style.height = - this.canvasHeight + 2 * THUMBNAIL_CANVAS_BORDER_WIDTH + 'px'; + var borderAdjustment = 2 * THUMBNAIL_CANVAS_BORDER_WIDTH; + ring.style.width = this.canvasWidth + borderAdjustment + 'px'; + ring.style.height = this.canvasHeight + borderAdjustment + 'px'; this.ring = ring; div.appendChild(ring); anchor.appendChild(div); container.appendChild(anchor); - - this.hasImage = false; - this.renderingState = RenderingStates.INITIAL; - this.renderingQueue = renderingQueue; } PDFThumbnailView.prototype = { @@ -122,18 +126,14 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() { this.pdfPageRotate = pdfPage.rotate; var totalRotation = (this.rotation + this.pdfPageRotate) % 360; this.viewport = pdfPage.getViewport(1, totalRotation); - this.update(); + this.reset(); }, - update: function PDFThumbnailView_update(rotation) { - if (rotation !== undefined) { - this.rotation = rotation; - } - var totalRotation = (this.rotation + this.pdfPageRotate) % 360; - this.viewport = this.viewport.clone({ - scale: 1, - rotation: totalRotation - }); + reset: function PDFThumbnailView_reset() { + this.hasImage = false; + this.resume = null; + this.renderingState = RenderingStates.INITIAL; + this.pageWidth = this.viewport.width; this.pageHeight = this.viewport.height; this.pageRatio = this.pageWidth / this.pageHeight; @@ -142,20 +142,42 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() { this.scale = (this.canvasWidth / this.pageWidth); this.div.removeAttribute('data-loaded'); - this.ring.textContent = ''; - this.ring.style.width = - this.canvasWidth + 2 * THUMBNAIL_CANVAS_BORDER_WIDTH + 'px'; - this.ring.style.height = - this.canvasHeight + 2 * THUMBNAIL_CANVAS_BORDER_WIDTH + 'px'; + var ring = this.ring; + var childNodes = ring.childNodes; + for (var i = childNodes.length - 1; i >= 0; i--) { + ring.removeChild(childNodes[i]); + } + var borderAdjustment = 2 * THUMBNAIL_CANVAS_BORDER_WIDTH; + ring.style.width = this.canvasWidth + borderAdjustment + 'px'; + ring.style.height = this.canvasHeight + borderAdjustment + 'px'; - this.hasImage = false; - this.renderingState = RenderingStates.INITIAL; - this.resume = null; + if (this.canvas) { + // Zeroing the width and height causes Firefox to release graphics + // resources immediately, which can greatly reduce memory consumption. + this.canvas.width = 0; + this.canvas.height = 0; + delete this.canvas; + } }, - getPageDrawContext: function PDFThumbnailView_getPageDrawContext() { + update: function PDFThumbnailView_update(rotation) { + if (typeof rotation !== 'undefined') { + this.rotation = rotation; + } + var totalRotation = (this.rotation + this.pdfPageRotate) % 360; + this.viewport = this.viewport.clone({ + scale: 1, + rotation: totalRotation + }); + this.reset(); + }, + + /** + * @private + */ + _getPageDrawContext: function PDFThumbnailView_getPageDrawContext() { var canvas = document.createElement('canvas'); - canvas.id = 'thumbnail' + this.id; + canvas.id = this.renderingId; canvas.width = this.canvasWidth; canvas.height = this.canvasHeight; @@ -163,8 +185,8 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() { canvas.setAttribute('aria-label', mozL10n.get('thumb_page_canvas', {page: this.id}, 'Thumbnail of Page {{page}}')); + this.canvas = canvas; this.div.setAttribute('data-loaded', true); - this.ring.appendChild(canvas); return canvas.getContext('2d'); @@ -178,25 +200,25 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() { if (this.renderingState !== RenderingStates.INITIAL) { console.error('Must be in new state before drawing'); } - - this.renderingState = RenderingStates.RUNNING; if (this.hasImage) { return Promise.resolve(undefined); } + this.hasImage = true; + this.renderingState = RenderingStates.RUNNING; var resolveRenderPromise, rejectRenderPromise; var promise = new Promise(function (resolve, reject) { - resolveRenderPromise = resolve; - rejectRenderPromise = reject; - }); + resolveRenderPromise = resolve; + rejectRenderPromise = reject; + }); var self = this; - var ctx = this.getPageDrawContext(); + var ctx = this._getPageDrawContext(); var drawViewport = this.viewport.clone({ scale: this.scale }); var renderContext = { canvasContext: ctx, viewport: drawViewport, - continueCallback: function(cont) { + continueCallback: function renderContinueCallback(cont) { if (!self.renderingQueue.isHighestPriority(self)) { self.renderingState = RenderingStates.PAUSED; self.resume = function() { @@ -218,7 +240,6 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() { rejectRenderPromise(error); } ); - this.hasImage = true; return promise; }, @@ -230,41 +251,39 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() { if (!this.pdfPage) { this.setPdfPage(pageView.pdfPage); } + this.hasImage = true; this.renderingState = RenderingStates.FINISHED; - var ctx = this.getPageDrawContext(); + + var ctx = this._getPageDrawContext(); var canvas = ctx.canvas; if (img.width <= 2 * canvas.width) { ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height); - } else { - // drawImage does an awful job of rescaling the image, - // doing it gradually. - var MAX_NUM_SCALING_STEPS = 3; - var reducedWidth = canvas.width << MAX_NUM_SCALING_STEPS; - var reducedHeight = canvas.height << MAX_NUM_SCALING_STEPS; - var reducedImage = getTempCanvas(reducedWidth, reducedHeight); - var reducedImageCtx = reducedImage.getContext('2d'); - - while (reducedWidth > img.width || reducedHeight > img.height) { - reducedWidth >>= 1; - reducedHeight >>= 1; - } - reducedImageCtx.drawImage(img, 0, 0, img.width, img.height, - 0, 0, reducedWidth, reducedHeight); - while (reducedWidth > 2 * canvas.width) { - reducedImageCtx.drawImage(reducedImage, - 0, 0, reducedWidth, reducedHeight, - 0, 0, - reducedWidth >> 1, reducedHeight >> 1); - reducedWidth >>= 1; - reducedHeight >>= 1; - } - ctx.drawImage(reducedImage, 0, 0, reducedWidth, reducedHeight, - 0, 0, canvas.width, canvas.height); + return; } + // drawImage does an awful job of rescaling the image, doing it gradually. + var MAX_NUM_SCALING_STEPS = 3; + var reducedWidth = canvas.width << MAX_NUM_SCALING_STEPS; + var reducedHeight = canvas.height << MAX_NUM_SCALING_STEPS; + var reducedImage = getTempCanvas(reducedWidth, reducedHeight); + var reducedImageCtx = reducedImage.getContext('2d'); - this.hasImage = true; + while (reducedWidth > img.width || reducedHeight > img.height) { + reducedWidth >>= 1; + reducedHeight >>= 1; + } + reducedImageCtx.drawImage(img, 0, 0, img.width, img.height, + 0, 0, reducedWidth, reducedHeight); + while (reducedWidth > 2 * canvas.width) { + reducedImageCtx.drawImage(reducedImage, + 0, 0, reducedWidth, reducedHeight, + 0, 0, reducedWidth >> 1, reducedHeight >> 1); + reducedWidth >>= 1; + reducedHeight >>= 1; + } + ctx.drawImage(reducedImage, 0, 0, reducedWidth, reducedHeight, + 0, 0, canvas.width, canvas.height); } }; diff --git a/web/pdf_thumbnail_viewer.js b/web/pdf_thumbnail_viewer.js index db464fc3b..170fa19ac 100644 --- a/web/pdf_thumbnail_viewer.js +++ b/web/pdf_thumbnail_viewer.js @@ -104,6 +104,13 @@ var PDFThumbnailViewer = (function PDFThumbnailViewerClosure() { }, cleanup: function PDFThumbnailViewer_cleanup() { + var tempCanvas = PDFThumbnailView.tempImageCache; + if (tempCanvas) { + // Zeroing the width and height causes Firefox to release graphics + // resources immediately, which can greatly reduce memory consumption. + tempCanvas.width = 0; + tempCanvas.height = 0; + } PDFThumbnailView.tempImageCache = null; }, From b7041f81f478d2b89eb640451f303140e72271df Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sun, 25 Jan 2015 16:59:57 +0100 Subject: [PATCH 6/7] Enable cancelling of thumbnail drawing This is useful if thumbnails are being rendered when the document is rotated, since it let us abort the current rendering. --- web/pdf_thumbnail_view.js | 57 ++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js index 26a2a52ca..9a1e23db9 100644 --- a/web/pdf_thumbnail_view.js +++ b/web/pdf_thumbnail_view.js @@ -130,6 +130,9 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() { }, reset: function PDFThumbnailView_reset() { + if (this.renderTask) { + this.renderTask.cancel(); + } this.hasImage = false; this.resume = null; this.renderingState = RenderingStates.INITIAL; @@ -213,31 +216,53 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() { }); var self = this; + function thumbnailDrawCallback(error) { + // The renderTask may have been replaced by a new one, so only remove + // the reference to the renderTask if it matches the one that is + // triggering this callback. + if (renderTask === self.renderTask) { + self.renderTask = null; + } + if (error === 'cancelled') { + rejectRenderPromise(error); + return; + } + self.renderingState = RenderingStates.FINISHED; + + if (!error) { + resolveRenderPromise(undefined); + } else { + rejectRenderPromise(error); + } + } + var ctx = this._getPageDrawContext(); var drawViewport = this.viewport.clone({ scale: this.scale }); + var renderContinueCallback = function renderContinueCallback(cont) { + if (!self.renderingQueue.isHighestPriority(self)) { + self.renderingState = RenderingStates.PAUSED; + self.resume = function resumeCallback() { + self.renderingState = RenderingStates.RUNNING; + cont(); + }; + return; + } + cont(); + }; + var renderContext = { canvasContext: ctx, viewport: drawViewport, - continueCallback: function renderContinueCallback(cont) { - if (!self.renderingQueue.isHighestPriority(self)) { - self.renderingState = RenderingStates.PAUSED; - self.resume = function() { - self.renderingState = RenderingStates.RUNNING; - cont(); - }; - return; - } - cont(); - } + continueCallback: renderContinueCallback }; - this.pdfPage.render(renderContext).promise.then( + var renderTask = this.renderTask = this.pdfPage.render(renderContext); + + renderTask.promise.then( function pdfPageRenderCallback() { - self.renderingState = RenderingStates.FINISHED; - resolveRenderPromise(undefined); + thumbnailDrawCallback(null); }, function pdfPageRenderError(error) { - self.renderingState = RenderingStates.FINISHED; - rejectRenderPromise(error); + thumbnailDrawCallback(error); } ); return promise; From 777d69b52ed2196cb69c851c07ae39421498ab65 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sat, 24 Jan 2015 16:29:32 +0100 Subject: [PATCH 7/7] Remove dead code from PDFThumbnailView --- web/pdf_thumbnail_view.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js index 9a1e23db9..dc5da0f83 100644 --- a/web/pdf_thumbnail_view.js +++ b/web/pdf_thumbnail_view.js @@ -195,10 +195,6 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() { return canvas.getContext('2d'); }, - drawingRequired: function PDFThumbnailView_drawingRequired() { - return !this.hasImage; - }, - draw: function PDFThumbnailView_draw() { if (this.renderingState !== RenderingStates.INITIAL) { console.error('Must be in new state before drawing');