diff --git a/test/unit/ui_utils_spec.js b/test/unit/ui_utils_spec.js index 1bbb175d6..84a2bed10 100644 --- a/test/unit/ui_utils_spec.js +++ b/test/unit/ui_utils_spec.js @@ -690,6 +690,38 @@ describe('ui_utils', function() { scrollOverDocument(pages, true); }); + it('handles views being empty', function() { + const scrollEl = { + scrollTop: 10, + scrollLeft: 0, + clientHeight: 750, + clientWidth: 1500, + }; + const views = []; + + expect(getVisibleElements(scrollEl, views)).toEqual({ + first: undefined, last: undefined, views: [], + }); + }); + + it('handles all views being hidden (without errors)', function() { + const scrollEl = { + scrollTop: 100000, + scrollLeft: 0, + clientHeight: 750, + clientWidth: 1500, + }; + const views = makePages([ + [[100, 150]], + [[100, 150]], + [[100, 150]], + ]); + + expect(getVisibleElements(scrollEl, views)).toEqual({ + first: undefined, last: undefined, views: [], + }); + }); + // This sub-suite is for a notionally internal helper function for // getVisibleElements. describe('backtrackBeforeAllVisibleElements', function() { diff --git a/web/app.js b/web/app.js index cdff6173a..26da5e818 100644 --- a/web/app.js +++ b/web/app.js @@ -996,6 +996,10 @@ let PDFViewerApplication = { pdfViewer.currentScaleValue = pdfViewer.currentScaleValue; // Re-apply the initial document location. this.setInitialView(hash); + }).catch(() => { + // Ensure that the document is always completely initialized, + // even if there are any errors thrown above. + this.setInitialView(); }).then(function() { // At this point, rendering of the initial page(s) should always have // started (and may even have completed). diff --git a/web/ui_utils.js b/web/ui_utils.js index cfe3e4104..7c1a6c110 100644 --- a/web/ui_utils.js +++ b/web/ui_utils.js @@ -444,7 +444,9 @@ function getVisibleElements(scrollEl, views, sortByVisibility = false, binarySearchFirstItem(views, horizontal ? isElementRightAfterViewLeft : isElementBottomAfterViewTop); - if (numViews > 0 && !horizontal) { + // Please note the return value of the `binarySearchFirstItem` function when + // no valid element is found (hence the `firstVisibleElementInd` check below). + if (numViews > 0 && firstVisibleElementInd < numViews && !horizontal) { // In wrapped scrolling (or vertical scrolling with spreads), with some page // sizes, isElementBottomAfterViewTop doesn't satisfy the binary search // condition: there can be pages with bottoms above the view top between