Merge pull request #10217 from Snuffleupagus/findagain-position-reset

For repeated 'findagain' operations, attempt to reset the search position if the user has e.g. scrolled in the document (issue 4141)
This commit is contained in:
Tim van der Meij 2018-11-03 16:05:41 +01:00 committed by GitHub
commit 45758dd2d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 68 additions and 5 deletions

View File

@ -878,6 +878,23 @@ class BaseViewer {
throw new Error('Not implemented: _getVisiblePages'); 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() { cleanup() {
for (let i = 0, ii = this._pages.length; i < ii; i++) { for (let i = 0, ii = this._pages.length; i < ii; i++) {
if (this._pages[i] && if (this._pages[i] &&

View File

@ -77,6 +77,11 @@ class IPDFLinkService {
* @param {Object} pageRef - reference to the page. * @param {Object} pageRef - reference to the page.
*/ */
cachePageRef(pageNum, pageRef) {} cachePageRef(pageNum, pageRef) {}
/**
* @param {number} pageNumber
*/
isPageVisible(pageNumber) {}
} }
/** /**

View File

@ -113,7 +113,7 @@ class PDFFindController {
executeCommand(cmd, state) { executeCommand(cmd, state) {
const pdfDocument = this._pdfDocument; const pdfDocument = this._pdfDocument;
if (this._state === null || cmd !== 'findagain') { if (this._state === null || this._shouldDirtyMatch(cmd)) {
this._dirtyMatch = true; this._dirtyMatch = true;
} }
this._state = state; this._state = state;
@ -128,6 +128,8 @@ class PDFFindController {
} }
this._extractText(); this._extractText();
const findbarClosed = !this._highlightMatches;
if (this._findTimeout) { if (this._findTimeout) {
clearTimeout(this._findTimeout); clearTimeout(this._findTimeout);
this._findTimeout = null; this._findTimeout = null;
@ -139,14 +141,16 @@ class PDFFindController {
this._nextMatch(); this._nextMatch();
this._findTimeout = null; this._findTimeout = null;
}, FIND_TIMEOUT); }, FIND_TIMEOUT);
} else if (cmd === 'findagain' && !this._dirtyMatch) { } else if (this._dirtyMatch) {
const updateHighlightAll = (!this._highlightMatches && // Immediately trigger searching for non-'find' operations, when the
this._state.highlightAll); // current state needs to be reset and matches re-calculated.
this._nextMatch();
} else if (cmd === 'findagain') {
this._nextMatch(); this._nextMatch();
// When the findbar was previously closed, and `highlightAll` is set, // When the findbar was previously closed, and `highlightAll` is set,
// ensure that the matches on all active pages are highlighted again. // ensure that the matches on all active pages are highlighted again.
if (updateHighlightAll) { if (findbarClosed && this._state.highlightAll) {
this._updateAllPages(); this._updateAllPages();
} }
} else { } else {
@ -194,6 +198,29 @@ class PDFFindController {
return this._normalizedQuery; return this._normalizedQuery;
} }
_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;
}
/** /**
* Helper for multi-term search that fills the `matchesWithLength` array * Helper for multi-term search that fills the `matchesWithLength` array
* and handles cases where one search term includes another search term (for * and handles cases where one search term includes another search term (for

View File

@ -352,6 +352,13 @@ class PDFLinkService {
let refStr = pageRef.num + ' ' + pageRef.gen + ' R'; let refStr = pageRef.num + ' ' + pageRef.gen + ' R';
return (this._pagesRefCache && this._pagesRefCache[refStr]) || null; return (this._pagesRefCache && this._pagesRefCache[refStr]) || null;
} }
/**
* @param {number} pageNumber
*/
isPageVisible(pageNumber) {
return this.pdfViewer.isPageVisible(pageNumber);
}
} }
function isValidExplicitDestination(dest) { function isValidExplicitDestination(dest) {
@ -483,6 +490,13 @@ class SimpleLinkService {
* @param {Object} pageRef - reference to the page. * @param {Object} pageRef - reference to the page.
*/ */
cachePageRef(pageNum, pageRef) {} cachePageRef(pageNum, pageRef) {}
/**
* @param {number} pageNumber
*/
isPageVisible(pageNumber) {
return true;
}
} }
export { export {