From 0cb074dc44b948d555bc0dd75e2e2bdc84403c90 Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Fri, 17 Apr 2015 15:56:48 -0500 Subject: [PATCH] Refactors PDFHistory. --- extensions/b2g/viewer.js | 16 +- web/interfaces.js | 11 + web/pdf_history.js | 622 ++++++++++++++++++------------------ web/pdf_viewer.component.js | 4 +- web/viewer.js | 29 +- 5 files changed, 366 insertions(+), 316 deletions(-) diff --git a/extensions/b2g/viewer.js b/extensions/b2g/viewer.js index 0059e4f5f7731..1cd75838e369e 100644 --- a/extensions/b2g/viewer.js +++ b/extensions/b2g/viewer.js @@ -30,6 +30,8 @@ var MAX_SCALE = 10.0; var PDFViewerApplication = { pdfDocument: null, pdfViewer: null, + pdfHistory: null, + pdfLinkService: null, loading: true, updateScaleControls: false, @@ -44,6 +46,8 @@ var PDFViewerApplication = { // Document loaded, specifying document for the viewer. this.pdfDocument = pdfDocument; this.pdfViewer.setDocument(pdfDocument); + this.pdfLinkService.setDocument(pdfDocument); + this.pdfHistory.initialize(pdfDocument.fingerprint); }.bind(this)); }, @@ -103,11 +107,21 @@ var PDFViewerApplication = { }, initUI: function pdfViewInitUI() { + var linkService = new PDFJS.PDFLinkService(); + this.pdfLinkService = linkService; + var container = document.getElementById('viewerContainer'); var pdfViewer = new PDFJS.PDFViewer({ - container: container + container: container, + linkService: linkService }); this.pdfViewer = pdfViewer; + linkService.setViewer(pdfViewer); + + this.pdfHistory = new PDFJS.PDFHistory({ + linkService: linkService + }); + linkService.setHistory(this.pdfHistory); container.addEventListener('pagesinit', function () { // we can use pdfViewer now, e.g. let's change default scale. diff --git a/web/interfaces.js b/web/interfaces.js index d21e1f4c54e3f..e096fe7492706 100644 --- a/web/interfaces.js +++ b/web/interfaces.js @@ -59,6 +59,17 @@ IPDFLinkService.prototype = { cachePageRef: function (pageNum, pageRef) {}, }; +/** + * @interface + */ +function IPDFHistory() {} +IPDFHistory.prototype = { + forward: function () {}, + back: function () {}, + push: function (params) {}, + updateNextHashParam: function (hash) {}, +}; + /** * @interface */ diff --git a/web/pdf_history.js b/web/pdf_history.js index e15e03a66d595..a1a8db9cfdbcc 100644 --- a/web/pdf_history.js +++ b/web/pdf_history.js @@ -18,129 +18,136 @@ 'use strict'; -var PDFHistory = { - initialized: false, - initialDestination: null, - - /** - * @param {string} fingerprint - * @param {IPDFLinkService} linkService - */ - initialize: function pdfHistoryInitialize(fingerprint, linkService) { - this.initialized = true; - this.reInitialized = false; - this.allowHashChange = true; - this.historyUnlocked = true; - - this.previousHash = window.location.hash.substring(1); - this.currentBookmark = ''; - this.currentPage = 0; - this.updatePreviousBookmark = false; - this.previousBookmark = ''; - this.previousPage = 0; - this.nextHashParam = ''; - - this.fingerprint = fingerprint; - this.linkService = linkService; - this.currentUid = this.uid = 0; - this.current = {}; - - var state = window.history.state; - if (this._isStateObjectDefined(state)) { - // This corresponds to navigating back to the document - // from another page in the browser history. - if (state.target.dest) { - this.initialDestination = state.target.dest; + +var PDFHistory = (function () { + function PDFHistory(options) { + this.linkService = options.linkService; + + this.initialized = false; + this.initialDestination = null; + } + + PDFHistory.prototype = { + /** + * @param {string} fingerprint + * @param {IPDFLinkService} linkService + */ + initialize: function pdfHistoryInitialize(fingerprint) { + this.initialized = true; + this.reInitialized = false; + this.allowHashChange = true; + this.historyUnlocked = true; + + this.previousHash = window.location.hash.substring(1); + this.currentBookmark = ''; + this.currentPage = 0; + this.updatePreviousBookmark = false; + this.previousBookmark = ''; + this.previousPage = 0; + this.nextHashParam = ''; + + this.fingerprint = fingerprint; + this.currentUid = this.uid = 0; + this.current = {}; + + var state = window.history.state; + if (this._isStateObjectDefined(state)) { + // This corresponds to navigating back to the document + // from another page in the browser history. + if (state.target.dest) { + this.initialDestination = state.target.dest; + } else { + this.linkService.setHash(state.target.hash); + } + this.currentUid = state.uid; + this.uid = state.uid + 1; + this.current = state.target; } else { - linkService.setHash(state.target.hash); - } - this.currentUid = state.uid; - this.uid = state.uid + 1; - this.current = state.target; - } else { - // This corresponds to the loading of a new document. - if (state && state.fingerprint && + // This corresponds to the loading of a new document. + if (state && state.fingerprint && this.fingerprint !== state.fingerprint) { - // Reinitialize the browsing history when a new document - // is opened in the web viewer. - this.reInitialized = true; + // Reinitialize the browsing history when a new document + // is opened in the web viewer. + this.reInitialized = true; + } + this._pushOrReplaceState({fingerprint: this.fingerprint}, true); } - this._pushOrReplaceState({ fingerprint: this.fingerprint }, true); - } - var self = this; - window.addEventListener('popstate', function pdfHistoryPopstate(evt) { - evt.preventDefault(); - evt.stopPropagation(); + var self = this; + window.addEventListener('popstate', function pdfHistoryPopstate(evt) { + evt.preventDefault(); + evt.stopPropagation(); - if (!self.historyUnlocked) { - return; - } - if (evt.state) { - // Move back/forward in the history. - self._goTo(evt.state); - } else { - // Handle the user modifying the hash of a loaded document. - self.previousHash = window.location.hash.substring(1); - - // If the history is empty when the hash changes, - // update the previous entry in the browser history. - if (self.uid === 0) { - var previousParams = (self.previousHash && self.currentBookmark && - self.previousHash !== self.currentBookmark) ? - { hash: self.currentBookmark, page: self.currentPage } : - { page: 1 }; - self.historyUnlocked = false; - self.allowHashChange = false; - window.history.back(); - self._pushToHistory(previousParams, false, true); - window.history.forward(); - self.historyUnlocked = true; + if (!self.historyUnlocked) { + return; } - self._pushToHistory({ hash: self.previousHash }, false, true); - self._updatePreviousBookmark(); - } - }, false); - - function pdfHistoryBeforeUnload() { - var previousParams = self._getPreviousParams(null, true); - if (previousParams) { - var replacePrevious = (!self.current.dest && - self.current.hash !== self.previousHash); - self._pushToHistory(previousParams, false, replacePrevious); - self._updatePreviousBookmark(); + if (evt.state) { + // Move back/forward in the history. + self._goTo(evt.state); + } else { + // Handle the user modifying the hash of a loaded document. + self.previousHash = window.location.hash.substring(1); + + // If the history is empty when the hash changes, + // update the previous entry in the browser history. + if (self.uid === 0) { + var previousParams = (self.previousHash && self.currentBookmark && + self.previousHash !== self.currentBookmark) ? + {hash: self.currentBookmark, page: self.currentPage} : + {page: 1}; + self.historyUnlocked = false; + self.allowHashChange = false; + window.history.back(); + self._pushToHistory(previousParams, false, true); + window.history.forward(); + self.historyUnlocked = true; + } + self._pushToHistory({hash: self.previousHash}, false, true); + self._updatePreviousBookmark(); + } + }, false); + + function pdfHistoryBeforeUnload() { + var previousParams = self._getPreviousParams(null, true); + if (previousParams) { + var replacePrevious = (!self.current.dest && + self.current.hash !== self.previousHash); + self._pushToHistory(previousParams, false, replacePrevious); + self._updatePreviousBookmark(); + } + // Remove the event listener when navigating away from the document, + // since 'beforeunload' prevents Firefox from caching the document. + window.removeEventListener('beforeunload', pdfHistoryBeforeUnload, + false); } - // Remove the event listener when navigating away from the document, - // since 'beforeunload' prevents Firefox from caching the document. - window.removeEventListener('beforeunload', pdfHistoryBeforeUnload, false); - } - window.addEventListener('beforeunload', pdfHistoryBeforeUnload, false); - window.addEventListener('pageshow', function pdfHistoryPageShow(evt) { - // If the entire viewer (including the PDF file) is cached in the browser, - // we need to reattach the 'beforeunload' event listener since - // the 'DOMContentLoaded' event is not fired on 'pageshow'. window.addEventListener('beforeunload', pdfHistoryBeforeUnload, false); - }, false); - }, - - _isStateObjectDefined: function pdfHistory_isStateObjectDefined(state) { - return (state && state.uid >= 0 && - state.fingerprint && this.fingerprint === state.fingerprint && - state.target && state.target.hash) ? true : false; - }, - - _pushOrReplaceState: function pdfHistory_pushOrReplaceState(stateObj, - replace) { - if (replace) { + + window.addEventListener('pageshow', function pdfHistoryPageShow(evt) { + // If the entire viewer (including the PDF file) is cached in + // the browser, we need to reattach the 'beforeunload' event listener + // since the 'DOMContentLoaded' event is not fired on 'pageshow'. + window.addEventListener('beforeunload', pdfHistoryBeforeUnload, false); + }, false); + }, + + _isStateObjectDefined: function pdfHistory_isStateObjectDefined(state) { + return (state && state.uid >= 0 && + state.fingerprint && this.fingerprint === state.fingerprint && + state.target && state.target.hash) ? true : false; + }, + + _pushOrReplaceState: function pdfHistory_pushOrReplaceState(stateObj, + replace) { + if (replace) { //#if (GENERIC || CHROME) - window.history.replaceState(stateObj, '', document.URL); + window.history.replaceState(stateObj, '', document.URL); //#else // window.history.replaceState(stateObj, ''); //#endif - } else { + } else { //#if (GENERIC || CHROME) - window.history.pushState(stateObj, '', document.URL); + window.history.pushState(stateObj, '', document.URL); //#else // window.history.pushState(stateObj, ''); //#endif @@ -149,230 +156,235 @@ var PDFHistory = { // chrome.runtime.sendMessage('showPageAction'); // } //#endif - } - }, + } + }, - get isHashChangeUnlocked() { - if (!this.initialized) { - return true; - } - // If the current hash changes when moving back/forward in the history, - // this will trigger a 'popstate' event *as well* as a 'hashchange' event. - // Since the hash generally won't correspond to the exact the position - // stored in the history's state object, triggering the 'hashchange' event - // can thus corrupt the browser history. - // - // When the hash changes during a 'popstate' event, we *only* prevent the - // first 'hashchange' event and immediately reset allowHashChange. - // If it is not reset, the user would not be able to change the hash. - - var temp = this.allowHashChange; - this.allowHashChange = true; - return temp; - }, - - _updatePreviousBookmark: function pdfHistory_updatePreviousBookmark() { - if (this.updatePreviousBookmark && - this.currentBookmark && this.currentPage) { - this.previousBookmark = this.currentBookmark; - this.previousPage = this.currentPage; - this.updatePreviousBookmark = false; - } - }, - - updateCurrentBookmark: function pdfHistoryUpdateCurrentBookmark(bookmark, - pageNum) { - if (this.initialized) { - this.currentBookmark = bookmark.substring(1); - this.currentPage = pageNum | 0; - this._updatePreviousBookmark(); - } - }, + get isHashChangeUnlocked() { + if (!this.initialized) { + return true; + } + // If the current hash changes when moving back/forward in the history, + // this will trigger a 'popstate' event *as well* as a 'hashchange' event. + // Since the hash generally won't correspond to the exact the position + // stored in the history's state object, triggering the 'hashchange' event + // can thus corrupt the browser history. + // + // When the hash changes during a 'popstate' event, we *only* prevent the + // first 'hashchange' event and immediately reset allowHashChange. + // If it is not reset, the user would not be able to change the hash. - updateNextHashParam: function pdfHistoryUpdateNextHashParam(param) { - if (this.initialized) { - this.nextHashParam = param; - } - }, + var temp = this.allowHashChange; + this.allowHashChange = true; + return temp; + }, - push: function pdfHistoryPush(params, isInitialBookmark) { - if (!(this.initialized && this.historyUnlocked)) { - return; - } - if (params.dest && !params.hash) { - params.hash = (this.current.hash && this.current.dest && - this.current.dest === params.dest) ? - this.current.hash : - this.linkService.getDestinationHash(params.dest).split('#')[1]; - } - if (params.page) { - params.page |= 0; - } - if (isInitialBookmark) { - var target = window.history.state.target; - if (!target) { - // Invoked when the user specifies an initial bookmark, - // thus setting initialBookmark, when the document is loaded. - this._pushToHistory(params, false); - this.previousHash = window.location.hash.substring(1); + _updatePreviousBookmark: function pdfHistory_updatePreviousBookmark() { + if (this.updatePreviousBookmark && + this.currentBookmark && this.currentPage) { + this.previousBookmark = this.currentBookmark; + this.previousPage = this.currentPage; + this.updatePreviousBookmark = false; } - this.updatePreviousBookmark = this.nextHashParam ? false : true; - if (target) { - // If the current document is reloaded, - // avoid creating duplicate entries in the history. + }, + + updateCurrentBookmark: function pdfHistoryUpdateCurrentBookmark(bookmark, + pageNum) { + if (this.initialized) { + this.currentBookmark = bookmark.substring(1); + this.currentPage = pageNum | 0; this._updatePreviousBookmark(); } - return; - } - if (this.nextHashParam) { - if (this.nextHashParam === params.hash) { - this.nextHashParam = null; - this.updatePreviousBookmark = true; - return; - } else { - this.nextHashParam = null; + }, + + updateNextHashParam: function pdfHistoryUpdateNextHashParam(param) { + if (this.initialized) { + this.nextHashParam = param; } - } + }, - if (params.hash) { - if (this.current.hash) { - if (this.current.hash !== params.hash) { - this._pushToHistory(params, true); + push: function pdfHistoryPush(params, isInitialBookmark) { + if (!(this.initialized && this.historyUnlocked)) { + return; + } + if (params.dest && !params.hash) { + params.hash = (this.current.hash && this.current.dest && + this.current.dest === params.dest) ? + this.current.hash : + this.linkService.getDestinationHash(params.dest).split('#')[1]; + } + if (params.page) { + params.page |= 0; + } + if (isInitialBookmark) { + var target = window.history.state.target; + if (!target) { + // Invoked when the user specifies an initial bookmark, + // thus setting initialBookmark, when the document is loaded. + this._pushToHistory(params, false); + this.previousHash = window.location.hash.substring(1); + } + this.updatePreviousBookmark = this.nextHashParam ? false : true; + if (target) { + // If the current document is reloaded, + // avoid creating duplicate entries in the history. + this._updatePreviousBookmark(); + } + return; + } + if (this.nextHashParam) { + if (this.nextHashParam === params.hash) { + this.nextHashParam = null; + this.updatePreviousBookmark = true; + return; } else { - if (!this.current.page && params.page) { - this._pushToHistory(params, false, true); + this.nextHashParam = null; + } + } + + if (params.hash) { + if (this.current.hash) { + if (this.current.hash !== params.hash) { + this._pushToHistory(params, true); + } else { + if (!this.current.page && params.page) { + this._pushToHistory(params, false, true); + } + this.updatePreviousBookmark = true; } - this.updatePreviousBookmark = true; + } else { + this._pushToHistory(params, true); } - } else { + } else if (this.current.page && params.page && + this.current.page !== params.page) { this._pushToHistory(params, true); } - } else if (this.current.page && params.page && - this.current.page !== params.page) { - this._pushToHistory(params, true); - } - }, + }, - _getPreviousParams: function pdfHistory_getPreviousParams(onlyCheckPage, - beforeUnload) { - if (!(this.currentBookmark && this.currentPage)) { - return null; - } else if (this.updatePreviousBookmark) { - this.updatePreviousBookmark = false; - } - if (this.uid > 0 && !(this.previousBookmark && this.previousPage)) { - // Prevent the history from getting stuck in the current state, - // effectively preventing the user from going back/forward in the history. - // - // This happens if the current position in the document didn't change when - // the history was previously updated. The reasons for this are either: - // 1. The current zoom value is such that the document does not need to, - // or cannot, be scrolled to display the destination. - // 2. The previous destination is broken, and doesn't actally point to a - // position within the document. - // (This is either due to a bad PDF generator, or the user making a - // mistake when entering a destination in the hash parameters.) - return null; - } - if ((!this.current.dest && !onlyCheckPage) || beforeUnload) { - if (this.previousBookmark === this.currentBookmark) { + _getPreviousParams: function pdfHistory_getPreviousParams(onlyCheckPage, + beforeUnload) { + if (!(this.currentBookmark && this.currentPage)) { return null; + } else if (this.updatePreviousBookmark) { + this.updatePreviousBookmark = false; } - } else if (this.current.page || onlyCheckPage) { - if (this.previousPage === this.currentPage) { + if (this.uid > 0 && !(this.previousBookmark && this.previousPage)) { + // Prevent the history from getting stuck in the current state, + // effectively preventing the user from going back/forward in + // the history. + // + // This happens if the current position in the document didn't change + // when the history was previously updated. The reasons for this are + // either: + // 1. The current zoom value is such that the document does not need to, + // or cannot, be scrolled to display the destination. + // 2. The previous destination is broken, and doesn't actally point to a + // position within the document. + // (This is either due to a bad PDF generator, or the user making a + // mistake when entering a destination in the hash parameters.) return null; } - } else { - return null; - } - var params = { hash: this.currentBookmark, page: this.currentPage }; - if (PresentationMode.active) { - params.hash = null; - } - return params; - }, + if ((!this.current.dest && !onlyCheckPage) || beforeUnload) { + if (this.previousBookmark === this.currentBookmark) { + return null; + } + } else if (this.current.page || onlyCheckPage) { + if (this.previousPage === this.currentPage) { + return null; + } + } else { + return null; + } + var params = {hash: this.currentBookmark, page: this.currentPage}; + if (PresentationMode.active) { + params.hash = null; + } + return params; + }, - _stateObj: function pdfHistory_stateObj(params) { - return { fingerprint: this.fingerprint, uid: this.uid, target: params }; - }, + _stateObj: function pdfHistory_stateObj(params) { + return {fingerprint: this.fingerprint, uid: this.uid, target: params}; + }, - _pushToHistory: function pdfHistory_pushToHistory(params, - addPrevious, overwrite) { - if (!this.initialized) { - return; - } - if (!params.hash && params.page) { - params.hash = ('page=' + params.page); - } - if (addPrevious && !overwrite) { - var previousParams = this._getPreviousParams(); - if (previousParams) { - var replacePrevious = (!this.current.dest && - this.current.hash !== this.previousHash); - this._pushToHistory(previousParams, false, replacePrevious); + _pushToHistory: function pdfHistory_pushToHistory(params, + addPrevious, overwrite) { + if (!this.initialized) { + return; } - } - this._pushOrReplaceState(this._stateObj(params), - (overwrite || this.uid === 0)); - this.currentUid = this.uid++; - this.current = params; - this.updatePreviousBookmark = true; - }, - - _goTo: function pdfHistory_goTo(state) { - if (!(this.initialized && this.historyUnlocked && - this._isStateObjectDefined(state))) { - return; - } - if (!this.reInitialized && state.uid < this.currentUid) { - var previousParams = this._getPreviousParams(true); - if (previousParams) { - this._pushToHistory(this.current, false); - this._pushToHistory(previousParams, false); - this.currentUid = state.uid; - window.history.back(); + if (!params.hash && params.page) { + params.hash = ('page=' + params.page); + } + if (addPrevious && !overwrite) { + var previousParams = this._getPreviousParams(); + if (previousParams) { + var replacePrevious = (!this.current.dest && + this.current.hash !== this.previousHash); + this._pushToHistory(previousParams, false, replacePrevious); + } + } + this._pushOrReplaceState(this._stateObj(params), + (overwrite || this.uid === 0)); + this.currentUid = this.uid++; + this.current = params; + this.updatePreviousBookmark = true; + }, + + _goTo: function pdfHistory_goTo(state) { + if (!(this.initialized && this.historyUnlocked && + this._isStateObjectDefined(state))) { return; } - } - this.historyUnlocked = false; + if (!this.reInitialized && state.uid < this.currentUid) { + var previousParams = this._getPreviousParams(true); + if (previousParams) { + this._pushToHistory(this.current, false); + this._pushToHistory(previousParams, false); + this.currentUid = state.uid; + window.history.back(); + return; + } + } + this.historyUnlocked = false; - if (state.target.dest) { - this.linkService.navigateTo(state.target.dest); - } else { - this.linkService.setHash(state.target.hash); - } - this.currentUid = state.uid; - if (state.uid > this.uid) { - this.uid = state.uid; - } - this.current = state.target; - this.updatePreviousBookmark = true; + if (state.target.dest) { + this.linkService.navigateTo(state.target.dest); + } else { + this.linkService.setHash(state.target.hash); + } + this.currentUid = state.uid; + if (state.uid > this.uid) { + this.uid = state.uid; + } + this.current = state.target; + this.updatePreviousBookmark = true; - var currentHash = window.location.hash.substring(1); - if (this.previousHash !== currentHash) { - this.allowHashChange = false; - } - this.previousHash = currentHash; + var currentHash = window.location.hash.substring(1); + if (this.previousHash !== currentHash) { + this.allowHashChange = false; + } + this.previousHash = currentHash; - this.historyUnlocked = true; - }, + this.historyUnlocked = true; + }, - back: function pdfHistoryBack() { - this.go(-1); - }, + back: function pdfHistoryBack() { + this.go(-1); + }, - forward: function pdfHistoryForward() { - this.go(1); - }, + forward: function pdfHistoryForward() { + this.go(1); + }, - go: function pdfHistoryGo(direction) { - if (this.initialized && this.historyUnlocked) { - var state = window.history.state; - if (direction === -1 && state && state.uid > 0) { - window.history.back(); - } else if (direction === 1 && state && state.uid < (this.uid - 1)) { - window.history.forward(); + go: function pdfHistoryGo(direction) { + if (this.initialized && this.historyUnlocked) { + var state = window.history.state; + if (direction === -1 && state && state.uid > 0) { + window.history.back(); + } else if (direction === 1 && state && state.uid < (this.uid - 1)) { + window.history.forward(); + } } } - } -}; + }; + + return PDFHistory; +})(); diff --git a/web/pdf_viewer.component.js b/web/pdf_viewer.component.js index 400f3f58cfab8..c59e98233d89c 100644 --- a/web/pdf_viewer.component.js +++ b/web/pdf_viewer.component.js @@ -16,7 +16,7 @@ */ /*jshint globalstrict: false */ /* globals PDFJS, PDFViewer, PDFPageView, TextLayerBuilder, PDFLinkService, - DefaultTextLayerFactory, AnnotationsLayerBuilder, + DefaultTextLayerFactory, AnnotationsLayerBuilder, PDFHistory, DefaultAnnotationsLayerFactory, getFileName */ // Initializing PDFJS global object (if still undefined) @@ -30,6 +30,7 @@ if (typeof PDFJS === 'undefined') { //#include ui_utils.js //#include pdf_link_service.js //#include pdf_viewer.js +//#include pdf_history.js PDFJS.PDFViewer = PDFViewer; PDFJS.PDFPageView = PDFPageView; @@ -38,6 +39,7 @@ if (typeof PDFJS === 'undefined') { PDFJS.DefaultTextLayerFactory = DefaultTextLayerFactory; PDFJS.AnnotationsLayerBuilder = AnnotationsLayerBuilder; PDFJS.DefaultAnnotationsLayerFactory = DefaultAnnotationsLayerFactory; + PDFJS.PDFHistory = PDFHistory; PDFJS.getFileName = getFileName; }).call((typeof window === 'undefined') ? this : window); diff --git a/web/viewer.js b/web/viewer.js index d19e30ac81b28..39130b9d699fa 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -97,6 +97,7 @@ var mozL10n = document.mozL10n || document.webL10n; var PDFViewerApplication = { initialBookmark: document.location.hash.substring(1), + initialDestination: null, initialized: false, fellback: false, pdfDocument: null, @@ -110,6 +111,8 @@ var PDFViewerApplication = { pdfRenderingQueue: null, /** @type {PDFLinkService} */ pdfLinkService: null, + /** @type {PDFHistory} */ + pdfHistory: null, pageRotation: 0, updateScaleControls: true, isInitialViewSet: false, @@ -153,6 +156,11 @@ var PDFViewerApplication = { Preferences.initialize(); + this.pdfHistory = new PDFHistory({ + linkService: pdfLinkService + }); + pdfLinkService.setHistory(this.pdfHistory); + this.findController = new PDFFindController({ pdfViewer: this.pdfViewer, integratedFind: this.supportsIntegratedFind @@ -766,7 +774,9 @@ var PDFViewerApplication = { if (!self.preferenceShowPreviousViewOnLoad && window.history.state) { window.history.replaceState(null, ''); } - PDFHistory.initialize(self.documentFingerprint, self.pdfLinkService); + self.pdfHistory.initialize(self.documentFingerprint, + self.pdfLinkService); + self.initialDestination = self.pdfHistory.initialDestination; } store.initializedPromise.then(function resolved() { @@ -942,12 +952,12 @@ var PDFViewerApplication = { document.getElementById('pageNumber').value = this.pdfViewer.currentPageNumber = 1; - if (PDFHistory.initialDestination) { - this.pdfLinkService.navigateTo(PDFHistory.initialDestination); - PDFHistory.initialDestination = null; + if (this.initialDestination) { + this.pdfLinkService.navigateTo(this.initialDestination); + this.initialDestination = null; } else if (this.initialBookmark) { this.pdfLinkService.setHash(this.initialBookmark); - PDFHistory.push({ hash: this.initialBookmark }, !!this.initialBookmark); + this.pdfHistory.push({ hash: this.initialBookmark }, true); this.initialBookmark = null; } else if (storedHash) { this.pdfLinkService.setHash(storedHash); @@ -1611,7 +1621,8 @@ window.addEventListener('updateviewarea', function () { document.getElementById('secondaryViewBookmark').href = href; // Update the current bookmark in the browsing history. - PDFHistory.updateCurrentBookmark(location.pdfOpenParams, location.pageNumber); + PDFViewerApplication.pdfHistory.updateCurrentBookmark(location.pdfOpenParams, + location.pageNumber); // Show/hide the loading indicator in the page number input element. var pageNumberInput = document.getElementById('pageNumber'); @@ -1641,7 +1652,7 @@ window.addEventListener('resize', function webViewerResize(evt) { }); window.addEventListener('hashchange', function webViewerHashchange(evt) { - if (PDFHistory.isHashChangeUnlocked) { + if (PDFViewerApplication.pdfHistory.isHashChangeUnlocked) { var hash = document.location.hash.substring(1); PDFViewerApplication.linkService.setHash(hash); } @@ -2053,13 +2064,13 @@ window.addEventListener('keydown', function keydown(evt) { switch (evt.keyCode) { case 37: // left arrow if (PresentationMode.active) { - PDFHistory.back(); + PDFViewerApplication.pdfHistory.back(); handled = true; } break; case 39: // right arrow if (PresentationMode.active) { - PDFHistory.forward(); + PDFViewerApplication.pdfHistory.forward(); handled = true; } break;