diff --git a/web/base_viewer.js b/web/base_viewer.js index 9588d75dc..19b3c344a 100644 --- a/web/base_viewer.js +++ b/web/base_viewer.js @@ -878,6 +878,23 @@ class BaseViewer { throw new Error('Not implemented: _getVisiblePages'); } + /** + * @param {number} pageNumber + */ + isPageVisible(pageNumber) { + if (!this.pdfDocument) { + return false; + } + if (this.pageNumber < 1 || pageNumber > this.pagesCount) { + console.error( + `${this._name}.isPageVisible: "${pageNumber}" is out of bounds.`); + return false; + } + return this._getVisiblePages().views.some(function(view) { + return (view.id === pageNumber); + }); + } + cleanup() { for (let i = 0, ii = this._pages.length; i < ii; i++) { if (this._pages[i] && diff --git a/web/interfaces.js b/web/interfaces.js index 170622681..55631555e 100644 --- a/web/interfaces.js +++ b/web/interfaces.js @@ -77,6 +77,11 @@ class IPDFLinkService { * @param {Object} pageRef - reference to the page. */ cachePageRef(pageNum, pageRef) {} + + /** + * @param {number} pageNumber + */ + isPageVisible(pageNumber) {} } /** diff --git a/web/pdf_find_controller.js b/web/pdf_find_controller.js index 7279a6ae5..3c1785124 100644 --- a/web/pdf_find_controller.js +++ b/web/pdf_find_controller.js @@ -201,6 +201,21 @@ class PDFFindController { _shouldDirtyMatch(cmd) { switch (cmd) { case 'findagain': + const pageNumber = this._selected.pageIdx + 1; + const linkService = this._linkService; + // Only treat a 'findagain' event as a new search operation when it's + // *absolutely* certain that the currently selected match is no longer + // visible, e.g. as a result of the user scrolling in the document. + // + // NOTE: If only a simple `this._linkService.page` check was used here, + // there's a risk that consecutive 'findagain' operations could "skip" + // over matches at the top/bottom of pages thus making them completely + // inaccessible when there's multiple pages visible in the viewer. + if (pageNumber >= 1 && pageNumber <= linkService.pagesCount && + linkService.page !== pageNumber && linkService.isPageVisible && + !linkService.isPageVisible(pageNumber)) { + break; + } return false; } return true; diff --git a/web/pdf_link_service.js b/web/pdf_link_service.js index 9fe9427b5..44bd88a34 100644 --- a/web/pdf_link_service.js +++ b/web/pdf_link_service.js @@ -352,6 +352,13 @@ class PDFLinkService { let refStr = pageRef.num + ' ' + pageRef.gen + ' R'; return (this._pagesRefCache && this._pagesRefCache[refStr]) || null; } + + /** + * @param {number} pageNumber + */ + isPageVisible(pageNumber) { + return this.pdfViewer.isPageVisible(pageNumber); + } } function isValidExplicitDestination(dest) { @@ -483,6 +490,13 @@ class SimpleLinkService { * @param {Object} pageRef - reference to the page. */ cachePageRef(pageNum, pageRef) {} + + /** + * @param {number} pageNumber + */ + isPageVisible(pageNumber) { + return true; + } } export {