diff --git a/web/app.js b/web/app.js index ed900ce309435..b23b159b909c5 100644 --- a/web/app.js +++ b/web/app.js @@ -1837,6 +1837,9 @@ const PDFViewerApplication = { this.setInitialView(hash); }) .catch(() => { + if (pdfDocument !== this.pdfDocument) { + return; // The document was closed while initializing. + } // Ensure that the document is always completely initialized, // even if there are any errors thrown above. this.setInitialView(); @@ -1857,6 +1860,9 @@ const PDFViewerApplication = { this._initializeAutoPrint(pdfDocument, openActionPromise); }, reason => { + if (pdfDocument !== this.pdfDocument) { + return; // The document was closed while the pages loaded. + } this._documentError("pdfjs-loading-error", { message: reason.message }); } ); diff --git a/web/pdf_scripting_manager.js b/web/pdf_scripting_manager.js index 8760fb9f4f94c..25b475c78cd95 100644 --- a/web/pdf_scripting_manager.js +++ b/web/pdf_scripting_manager.js @@ -361,7 +361,11 @@ class PDFScriptingManager { pdfViewer.currentPageNumber = value + 1; break; case "print": - await pdfViewer.pagesPromise; + try { + await pdfViewer.pagesPromise; + } catch { + break; // The document was closed, or failed to load. + } this.#eventBus.dispatch("print", { source: this }); break; case "println": diff --git a/web/pdf_viewer.js b/web/pdf_viewer.js index 2773526db9c72..0fc63d3ec5eb7 100644 --- a/web/pdf_viewer.js +++ b/web/pdf_viewer.js @@ -30,6 +30,7 @@ /** @typedef {import("./l10n.js").L10n} L10n */ import { + AbortException, AnnotationEditorType, AnnotationEditorUIManager, AnnotationMode, @@ -915,6 +916,10 @@ class PDFViewer { if (this.pdfDocument) { this.eventBus.dispatch("pagesdestroy", { source: this }); + // Ensure that `pagesPromise` doesn't remain pending forever, if the + // document was closed before all pages were loaded. + this._pagesCapability.reject(new AbortException("Document was closed.")); + this._cancelRendering(); this._resetView(); @@ -1196,6 +1201,10 @@ class PDFViewer { } }, reason => { + if (pdfDocument !== this.pdfDocument) { + return; // The document was closed while loading the page. + } + console.error( `Unable to get page ${pageNum} to initialize viewer`, reason @@ -1208,6 +1217,10 @@ class PDFViewer { if (pageNum % PagesCountLimit.PAUSE_EAGER_PAGE_INIT === 0) { await promise; + + if (pdfDocument !== this.pdfDocument) { + break; // The document was closed, stop fetching more pages. + } } } }); @@ -1228,6 +1241,10 @@ class PDFViewer { } }) .catch(reason => { + if (pdfDocument !== this.pdfDocument) { + return; // The document was closed while the first page loaded. + } + console.error("Unable to initialize viewer", reason); this._pagesCapability.reject(reason); @@ -2139,13 +2156,17 @@ class PDFViewer { if (pageView.pdfPage) { return pageView.pdfPage; } + const { pdfDocument } = this; try { - const pdfPage = await this.pdfDocument.getPage(pageView.id); + const pdfPage = await pdfDocument.getPage(pageView.id); if (!pageView.pdfPage) { pageView.setPdfPage(pdfPage); } return pdfPage; } catch (reason) { + if (pdfDocument !== this.pdfDocument) { + return null; // The document was closed while the page was loading. + } console.error("Unable to get page for page view", reason); return null; // Page error -- there is nothing that can be done. } @@ -2195,8 +2216,10 @@ class PDFViewer { ); if (pageView) { - this.#ensurePdfPageLoaded(pageView).then(() => { - this.renderingQueue.renderView(pageView); + this.#ensurePdfPageLoaded(pageView).then(pdfPage => { + if (pdfPage !== null) { + this.renderingQueue.renderView(pageView); + } }); return true; }