diff --git a/web/app.js b/web/app.js index 27dc2935f..7bc296bd4 100644 --- a/web/app.js +++ b/web/app.js @@ -1383,14 +1383,23 @@ const PDFViewerApplication = { onePageRendered.then(() => { pdfDocument.getOutline().then(outline => { + if (pdfDocument !== this.pdfDocument) { + return; // The document was closed while the outline resolved. + } this.pdfOutlineViewer.render({ outline, pdfDocument }); }); pdfDocument.getAttachments().then(attachments => { + if (pdfDocument !== this.pdfDocument) { + return; // The document was closed while the attachments resolved. + } this.pdfAttachmentViewer.render({ attachments }); }); // Ensure that the layers accurately reflects the current state in the // viewer itself, rather than the default state provided by the API. pdfViewer.optionalContentConfigPromise.then(optionalContentConfig => { + if (pdfDocument !== this.pdfDocument) { + return; // The document was closed while the layers resolved. + } this.pdfLayerViewer.render({ optionalContentConfig, pdfDocument }); }); if ( diff --git a/web/pdf_outline_viewer.js b/web/pdf_outline_viewer.js index 96c229012..09afc9bf3 100644 --- a/web/pdf_outline_viewer.js +++ b/web/pdf_outline_viewer.js @@ -53,6 +53,15 @@ class PDFOutlineViewer extends BaseTreeViewer { }); this.eventBus._on("pagesloaded", evt => { this._isPagesLoaded = !!evt.pagesCount; + + // If the capability is still pending, note the `_dispatchEvent`-method, + // we know that the `currentOutlineItem`-button should be enabled here. + if ( + this._currentOutlineItemCapability && + !this._currentOutlineItemCapability.settled + ) { + this._currentOutlineItemCapability.resolve(/* enabled = */ true); + } }); this.eventBus._on("sidebarviewchanged", evt => { this._sidebarView = evt.view; @@ -66,17 +75,32 @@ class PDFOutlineViewer extends BaseTreeViewer { this._pageNumberToDestHashCapability = null; this._currentPageNumber = 1; this._isPagesLoaded = false; + + if ( + this._currentOutlineItemCapability && + !this._currentOutlineItemCapability.settled + ) { + this._currentOutlineItemCapability.resolve(/* enabled = */ false); + } + this._currentOutlineItemCapability = null; } /** * @private */ _dispatchEvent(outlineCount) { + this._currentOutlineItemCapability = createPromiseCapability(); + if ( + outlineCount === 0 || + this._pdfDocument?.loadingParams.disableAutoFetch + ) { + this._currentOutlineItemCapability.resolve(/* enabled = */ false); + } + this.eventBus.dispatch("outlineloaded", { source: this, outlineCount, - enableCurrentOutlineItemButton: - outlineCount > 0 && !this._pdfDocument?.loadingParams.disableAutoFetch, + currentOutlineItemPromise: this._currentOutlineItemCapability.promise, }); } diff --git a/web/pdf_sidebar.js b/web/pdf_sidebar.js index 4faaa4da3..1e7e04ad0 100644 --- a/web/pdf_sidebar.js +++ b/web/pdf_sidebar.js @@ -425,11 +425,12 @@ class PDFSidebar { this.eventBus._on("outlineloaded", evt => { onTreeLoaded(evt.outlineCount, this.outlineButton, SidebarView.OUTLINE); - if (evt.enableCurrentOutlineItemButton) { - this.pdfViewer.pagesPromise.then(() => { - this._currentOutlineItemButton.disabled = !this.isInitialViewSet; - }); - } + evt.currentOutlineItemPromise.then(enabled => { + if (!this.isInitialViewSet) { + return; + } + this._currentOutlineItemButton.disabled = !enabled; + }); }); this.eventBus._on("attachmentsloaded", evt => {