diff --git a/web/page_view.js b/web/page_view.js index 86572cb89..109f0f515 100644 --- a/web/page_view.js +++ b/web/page_view.js @@ -353,7 +353,8 @@ var PageView = function pageView(container, id, scale, defaultViewport, return; } dest = null; - this.viewer.setScale(this.viewer.currentScaleValue, true, true); + // Fixes the case when PDF has different page sizes. + this.viewer.currentScaleValue = this.viewer.currentScaleValue; } if (!dest) { scrollIntoView(div); @@ -413,9 +414,9 @@ var PageView = function pageView(container, id, scale, defaultViewport, } if (scale && scale !== this.viewer.currentScale) { - this.viewer.setScale(scale, true, true); + this.viewer.currentScaleValue = scale; } else if (this.viewer.currentScale === UNKNOWN_SCALE) { - this.viewer.setScale(DEFAULT_SCALE, true, true); + this.viewer.currentScaleValue = DEFAULT_SCALE; } if (scale === 'page-fit' && !dest[4]) { diff --git a/web/pdf_viewer.js b/web/pdf_viewer.js index 1ea61bb5a..9bbba0931 100644 --- a/web/pdf_viewer.js +++ b/web/pdf_viewer.js @@ -53,7 +53,7 @@ var PDFViewer = (function pdfViewer() { this.lastScroll = 0; this.updateInProgress = false; this.presentationModeState = PresentationModeState.UNKNOWN; - this.resetView(); + this._resetView(); } PDFViewer.prototype = { @@ -65,28 +65,102 @@ var PDFViewer = (function pdfViewer() { return this.pages[index]; }, - setCurrentPageNumber: function (val) { + get currentPageNumber() { + return this._currentPageNumber; + }, + + set currentPageNumber(val) { + if (!this.pdfDocument) { + this._currentPageNumber = val; + return; + } + var event = document.createEvent('UIEvents'); event.initUIEvent('pagechange', true, true, window, 0); event.updateInProgress = this.updateInProgress; if (!(0 < val && val <= this.pagesCount)) { - this.previousPageNumber = val; event.pageNumber = this.page; + event.previousPageNumber = val; this.container.dispatchEvent(event); return; } this.pages[val - 1].updateStats(); - this.previousPageNumber = this.currentPageNumber; - this.currentPageNumber = val; + event.previousPageNumber = this._currentPageNumber; + this._currentPageNumber = val; event.pageNumber = val; this.container.dispatchEvent(event); }, + /** + * @returns {number} + */ + get currentScale() { + return this._currentScale; + }, + + /** + * @param {number} val - Scale of the pages in percents. + */ + set currentScale(val) { + if (isNaN(val)) { + throw new Error('Invalid numeric scale'); + } + if (!this.pdfDocument) { + this._currentScale = val; + this._currentScaleValue = val.toString(); + return; + } + this._setScale(val, false); + }, + + /** + * @returns {string} + */ + get currentScaleValue() { + return this._currentScaleValue; + }, + + /** + * @param val - The scale of the pages (in percent or predefined value). + */ + set currentScaleValue(val) { + if (!this.pdfDocument) { + this._currentScale = isNaN(val) ? UNKNOWN_SCALE : val; + this._currentScaleValue = val; + return; + } + this._setScale(val, false); + }, + + /** + * @returns {number} + */ + get pagesRotation() { + return this._pagesRotation; + }, + + /** + * @param {number} rotation - The rotation of the pages (0, 90, 180, 270). + */ + set pagesRotation(rotation) { + this._pagesRotation = rotation; + + for (var i = 0, l = this.pages.length; i < l; i++) { + var page = this.pages[i]; + page.update(page.scale, rotation); + } + + this._setScale(this._currentScaleValue, true); + }, + + /** + * @param pdfDocument {PDFDocument} + */ setDocument: function (pdfDocument) { if (this.pdfDocument) { - this.resetView(); + this._resetView(); } this.pdfDocument = pdfDocument; @@ -139,7 +213,7 @@ var PDFViewer = (function pdfViewer() { // Fetch a single page so we can get a viewport that will be the default // viewport for all pages return firstPagePromise.then(function(pdfPage) { - var scale = this.currentScale || 1.0; + var scale = this._currentScale || 1.0; var viewport = pdfPage.getViewport(scale * CSS_UNITS); for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) { var pageSource = new PDFPageSource(pdfDocument, pageNum); @@ -183,14 +257,14 @@ var PDFViewer = (function pdfViewer() { }.bind(this)); }, - resetView: function () { + _resetView: function () { this.cache = new Cache(DEFAULT_CACHE_SIZE); this.pages = []; - this.currentPageNumber = 1; - this.previousPageNumber = 1; - this.currentScale = UNKNOWN_SCALE; - this.currentScaleValue = null; + this._currentPageNumber = 1; + this._currentScale = UNKNOWN_SCALE; + this._currentScaleValue = null; this.location = null; + this._pagesRotation = 0; var container = this.viewer; while (container.hasChildNodes()) { @@ -208,18 +282,18 @@ var PDFViewer = (function pdfViewer() { }, _setScaleUpdatePages: function pdfViewer_setScaleUpdatePages( - newScale, newValue, resetAutoSettings, noScroll, preset) { - this.currentScaleValue = newValue; - if (newScale === this.currentScale) { + newScale, newValue, noScroll, preset) { + this._currentScaleValue = newValue; + if (newScale === this._currentScale) { return; } for (var i = 0, ii = this.pages.length; i < ii; i++) { this.pages[i].update(newScale); } - this.currentScale = newScale; + this._currentScale = newScale; if (!noScroll) { - var page = this.currentPageNumber, dest; + var page = this._currentPageNumber, dest; var inPresentationMode = this.presentationModeState === PresentationModeState.CHANGING || this.presentationModeState === PresentationModeState.FULLSCREEN; @@ -235,23 +309,22 @@ var PDFViewer = (function pdfViewer() { var event = document.createEvent('UIEvents'); event.initUIEvent('scalechange', true, true, window, 0); event.scale = newScale; - event.resetAutoSettings = resetAutoSettings; if (preset) { event.presetValue = newValue; } this.container.dispatchEvent(event); }, - setScale: function pdfViewer_setScale(value, resetAutoSettings, noScroll) { + _setScale: function pdfViewer_setScale(value, noScroll) { if (value === 'custom') { return; } var scale = parseFloat(value); if (scale > 0) { - this._setScaleUpdatePages(scale, value, true, noScroll, false); + this._setScaleUpdatePages(scale, value, noScroll, false); } else { - var currentPage = this.pages[this.currentPageNumber - 1]; + var currentPage = this.pages[this._currentPageNumber - 1]; if (!currentPage) { return; } @@ -287,23 +360,13 @@ var PDFViewer = (function pdfViewer() { '\' is an unknown zoom value.'); return; } - this._setScaleUpdatePages(scale, value, resetAutoSettings, noScroll, - true); + this._setScaleUpdatePages(scale, value, noScroll, true); } }, - updateRotation: function pdfViewRotatePages(rotation) { - for (var i = 0, l = this.pages.length; i < l; i++) { - var page = this.pages[i]; - page.update(page.scale, rotation); - } - - this.setScale(this.currentScaleValue, true, true); - }, - - updateLocation: function (firstPage) { - var currentScale = this.currentScale; - var currentScaleValue = this.currentScaleValue; + _updateLocation: function (firstPage) { + var currentScale = this._currentScale; + var currentScaleValue = this._currentScaleValue; var normalizedScaleValue = parseFloat(currentScaleValue) === currentScale ? Math.round(currentScale * 10000) / 100 : currentScaleValue; @@ -330,7 +393,7 @@ var PDFViewer = (function pdfViewer() { }, update: function () { - var visible = this.getVisiblePages(); + var visible = this._getVisiblePages(); var visiblePages = visible.views; if (visiblePages.length === 0) { return; @@ -354,7 +417,7 @@ var PDFViewer = (function pdfViewer() { if (page.percent < 100) { break; } - if (page.id === this.currentPageNumber) { + if (page.id === currentId) { stillFullyVisible = true; break; } @@ -365,10 +428,10 @@ var PDFViewer = (function pdfViewer() { } if (this.presentationModeState !== PresentationModeState.FULLSCREEN) { - this.setCurrentPageNumber(currentId); + this.currentPageNumber = currentId; } - this.updateLocation(firstPage); + this._updateLocation(firstPage); this.updateInProgress = false; @@ -394,14 +457,14 @@ var PDFViewer = (function pdfViewer() { false : (this.container.scrollWidth > this.container.clientWidth)); }, - getVisiblePages: function () { + _getVisiblePages: function () { if (this.presentationModeState !== PresentationModeState.FULLSCREEN) { return getVisibleElements(this.container, this.pages, true); } else { // The algorithm in getVisibleElements doesn't work in all browsers and // configurations when presentation mode is active. var visible = []; - var currentPage = this.pages[this.currentPageNumber - 1]; + var currentPage = this.pages[this._currentPageNumber - 1]; visible.push({ id: currentPage.id, view: currentPage }); return { first: currentPage, last: currentPage, views: visible }; } @@ -417,7 +480,7 @@ var PDFViewer = (function pdfViewer() { }, forceRendering: function (currentlyVisiblePages) { - var visiblePages = currentlyVisiblePages || this.getVisiblePages(); + var visiblePages = currentlyVisiblePages || this._getVisiblePages(); var pageView = this.renderingQueue.getHighestPriority(visiblePages, this.pages, this.scroll.down); diff --git a/web/thumbnail_view.js b/web/thumbnail_view.js index 313b2339d..205e31fd6 100644 --- a/web/thumbnail_view.js +++ b/web/thumbnail_view.js @@ -247,13 +247,12 @@ var PDFThumbnailViewer = (function pdfThumbnailViewer() { this.renderingQueue = options.renderingQueue; this.linkService = options.linkService; - this.scroll = watchScroll(this.container, this.scrollUpdated.bind(this)); - this.thumbnails = []; - this.currentPage = -1; + this.scroll = watchScroll(this.container, this._scrollUpdated.bind(this)); + this._resetView(); } PDFThumbnailViewer.prototype = { - scrollUpdated: function PDFThumbnailViewer_scrollUpdated() { + _scrollUpdated: function PDFThumbnailViewer_scrollUpdated() { this.renderingQueue.renderHighestPriority(); }, @@ -261,18 +260,18 @@ var PDFThumbnailViewer = (function pdfThumbnailViewer() { return this.thumbnails[index]; }, - getVisibleThumbs: function PDFThumbnailViewer_getVisibleThumbs() { + _getVisibleThumbs: function PDFThumbnailViewer_getVisibleThumbs() { return getVisibleElements(this.container, this.thumbnails); }, - updatePage: function (page) { + 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 visibleThumbs = this._getVisibleThumbs(); var numVisibleThumbs = visibleThumbs.views.length; // If the thumbnail isn't currently visible, scroll it into view. @@ -284,13 +283,17 @@ var PDFThumbnailViewer = (function pdfThumbnailViewer() { scrollIntoView(thumbnail, { top: THUMBNAIL_SCROLL_MARGIN }); } } - this.currentPage = page; }, - updateRotation: function (pageRotation) { + 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(pageRotation); + thumb.update(rotation); } }, @@ -298,6 +301,11 @@ var PDFThumbnailViewer = (function pdfThumbnailViewer() { ThumbnailView.tempImageCache = null; }, + _resetView: function () { + this.thumbnails = []; + this._pagesRotation = 0; + }, + setDocument: function (pdfDocument) { if (this.pdfDocument) { // cleanup of the elements and views @@ -305,7 +313,7 @@ var PDFThumbnailViewer = (function pdfThumbnailViewer() { while (thumbsView.hasChildNodes()) { thumbsView.removeChild(thumbsView.lastChild); } - this.thumbnails = []; + this._resetView(); } this.pdfDocument = pdfDocument; @@ -334,7 +342,7 @@ var PDFThumbnailViewer = (function pdfThumbnailViewer() { }, forceRendering: function () { - var visibleThumbs = this.getVisibleThumbs(); + var visibleThumbs = this._getVisibleThumbs(); var thumbView = this.renderingQueue.getHighestPriority(visibleThumbs, this.thumbnails, this.scroll.down); diff --git a/web/viewer.js b/web/viewer.js index 3d93ea964..99f277a57 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -96,6 +96,7 @@ var PDFView = { pdfThumbnailViewer: null, pdfRenderingQueue: null, pageRotation: 0, + updateScaleControls: true, mouseScrollTimeStamp: 0, mouseScrollDelta: 0, isViewerEmbedded: (window.parent !== window), @@ -258,7 +259,7 @@ var PDFView = { newScale = Math.ceil(newScale * 10) / 10; newScale = Math.min(MAX_SCALE, newScale); } while (--ticks && newScale < MAX_SCALE); - this.pdfViewer.setScale(newScale, true); + this.setScale(newScale, true); }, zoomOut: function pdfViewZoomOut(ticks) { @@ -268,7 +269,7 @@ var PDFView = { newScale = Math.floor(newScale * 10) / 10; newScale = Math.max(MIN_SCALE, newScale); } while (--ticks && newScale > MIN_SCALE); - this.pdfViewer.setScale(newScale, true); + this.setScale(newScale, true); }, get currentScaleValue() { @@ -280,7 +281,7 @@ var PDFView = { }, set page(val) { - this.pdfViewer.setCurrentPageNumber(val); + this.pdfViewer.currentPageNumber = val; }, get page() { @@ -825,6 +826,7 @@ var PDFView = { load: function pdfViewLoad(pdfDocument, scale) { var self = this; + scale = scale || UNKNOWN_SCALE; PDFView.findController.reset(); @@ -1061,14 +1063,14 @@ var PDFView = { } else if (storedHash) { this.setHash(storedHash); } else if (scale) { - this.pdfViewer.setScale(scale, true); + this.setScale(scale, true); this.page = 1; } if (PDFView.pdfViewer.currentScale === UNKNOWN_SCALE) { // Scale was not initialized: invalid bookmark or scale was not specified. // Setting the default one. - this.pdfViewer.setScale(DEFAULT_SCALE, true); + this.setScale(DEFAULT_SCALE, true); } }, @@ -1270,16 +1272,18 @@ var PDFView = { this.forceRendering(); }, - setScale: function (value, resetAutoSettings, noScroll) { - this.pdfViewer.setScale(value, resetAutoSettings, noScroll); + setScale: function (value, resetAutoSettings) { + this.updateScaleControls = !!resetAutoSettings; + this.pdfViewer.currentScaleValue = value; + this.updateScaleControls = true; }, rotatePages: function pdfViewRotatePages(delta) { var currentPage = this.getPageView(this.page - 1); this.pageRotation = (this.pageRotation + 360 + delta) % 360; - this.pdfViewer.updateRotation(this.pageRotation); - this.pdfThumbnailViewer.updateRotation(this.pageRotation); + this.pdfViewer.pagesRotation = this.pageRotation; + this.pdfThumbnailViewer.pagesRotation = this.pageRotation; this.forceRendering(); @@ -1590,7 +1594,7 @@ function webViewerInitialized() { document.getElementById('scaleSelect').addEventListener('change', function() { - PDFView.pdfViewer.setScale(this.value); + PDFView.setScale(this.value, false); }); document.getElementById('presentationMode').addEventListener('click', @@ -1730,7 +1734,7 @@ window.addEventListener('resize', function webViewerResize(evt) { (document.getElementById('pageWidthOption').selected || document.getElementById('pageFitOption').selected || document.getElementById('pageAutoOption').selected)) { - PDFView.pdfViewer.setScale(document.getElementById('scaleSelect').value); + PDFView.setScale(document.getElementById('scaleSelect').value, false); } updateViewarea(); @@ -1825,7 +1829,7 @@ window.addEventListener('scalechange', function scalechange(evt) { var customScaleOption = document.getElementById('customScaleOption'); customScaleOption.selected = false; - if (!evt.resetAutoSettings && + if (!PDFView.updateScaleControls && (document.getElementById('pageWidthOption').selected || document.getElementById('pageFitOption').selected || document.getElementById('pageAutoOption').selected)) { @@ -1849,9 +1853,9 @@ window.addEventListener('scalechange', function scalechange(evt) { window.addEventListener('pagechange', function pagechange(evt) { var page = evt.pageNumber; - if (PDFView.pdfViewer.previousPageNumber !== page) { + if (evt.previousPageNumber !== page) { document.getElementById('pageNumber').value = page; - PDFView.pdfThumbnailViewer.updatePage(page); + PDFView.pdfThumbnailViewer.scrollThumbnailIntoView(page); } var numPages = PDFView.pagesCount; @@ -1948,7 +1952,7 @@ window.addEventListener('keydown', function keydown(evt) { // keeping it unhandled (to restore page zoom to 100%) setTimeout(function () { // ... and resetting the scale after browser adjusts its scale - PDFView.pdfViewer.setScale(DEFAULT_SCALE, true); + PDFView.setScale(DEFAULT_SCALE, true); }); handled = false; break;