diff --git a/assets/main.css b/assets/main.css index 47f6124..a55ef3b 100644 --- a/assets/main.css +++ b/assets/main.css @@ -17,3 +17,13 @@ body { padding: 0; } + +#navigateBack::before { + -webkit-mask-image: url("navigation-back.svg"); + mask-image: url("navigation-back.svg"); +} + +#navigateForward::before { + -webkit-mask-image: url("navigation-forward.svg"); + mask-image: url("navigation-forward.svg"); +} diff --git a/assets/main.mjs b/assets/main.mjs index d22e5e2..c72f026 100644 --- a/assets/main.mjs +++ b/assets/main.mjs @@ -25,6 +25,45 @@ function loadConfig() { } const config = loadConfig(); +let updateNavigationHistory; + +function setupNavigationHistory() { + const application = window.PDFViewerApplication; + const history = application.pdfHistory; + const findButtonContainer = + document.getElementById("viewFindButton")?.parentElement; + + if (!(history && findButtonContainer)) { + return; + } + + const container = document.createElement("div"); + container.className = "toolbarHorizontalGroup hiddenSmallView"; + container.innerHTML = ` + +
+ `; + findButtonContainer.after(container); + + const backButton = document.getElementById("navigateBack"); + const forwardButton = document.getElementById("navigateForward"); + const updateButtons = () => { + backButton.disabled = !history.canGoBack; + forwardButton.disabled = !history.canGoForward; + }; + + backButton.addEventListener("click", () => history.back()); + forwardButton.addEventListener("click", () => history.forward()); + window.addEventListener("popstate", () => queueMicrotask(updateButtons)); + application.eventBus.on("updateviewarea", updateButtons); + + updateButtons(); + return updateButtons; +} PDFViewerApplicationOptions.set("defaultUrl", ""); PDFViewerApplicationOptions.set("disablePreferences", true); @@ -51,7 +90,9 @@ document.addEventListener( void (async () => { await window.PDFViewerApplication.initializedPromise; + updateNavigationHistory = setupNavigationHistory(); await window.PDFViewerApplication.open(config); + updateNavigationHistory?.(); const [, hash] = config.url.split("#"); if (hash) { window.PDFViewerApplication.pdfLinkService.setHash( @@ -72,6 +113,7 @@ window.addEventListener("message", async (event) => { currentPageNumber, window.PDFViewerApplication.pdfViewer.pagesCount ); + updateNavigationHistory?.(); break; } }); diff --git a/assets/navigation-back.svg b/assets/navigation-back.svg new file mode 100644 index 0000000..aff002d --- /dev/null +++ b/assets/navigation-back.svg @@ -0,0 +1,3 @@ + diff --git a/assets/navigation-forward.svg b/assets/navigation-forward.svg new file mode 100644 index 0000000..8bf9af7 --- /dev/null +++ b/assets/navigation-forward.svg @@ -0,0 +1,3 @@ + diff --git a/assets/pdf.js/web/viewer.mjs b/assets/pdf.js/web/viewer.mjs index c3d794a..88b109f 100644 --- a/assets/pdf.js/web/viewer.mjs +++ b/assets/pdf.js/web/viewer.mjs @@ -6373,6 +6373,14 @@ class PDFHistory { window.history.forward(); } } + get canGoBack() { + const state = window.history.state; + return this._initialized && !this._popStateInProgress && this.#isValidState(state) && state.uid > 0; + } + get canGoForward() { + const state = window.history.state; + return this._initialized && !this._popStateInProgress && this.#isValidState(state) && state.uid < this._maxUid; + } get popStateInProgress() { return this._initialized && (this._popStateInProgress || this._blockHashChange > 0); } @@ -6400,6 +6408,7 @@ class PDFHistory { if (shouldReplace) { window.history.replaceState(newState, "", newUrl); } else { + this._maxUid = newState.uid; window.history.pushState(newState, "", newUrl); } } @@ -13429,7 +13438,7 @@ const PDFViewerApplication = { }); pdfRenderingQueue.setThumbnailViewer(this.pdfThumbnailViewer); } - if (!this.isViewerEmbedded && !AppOptions.get("disableHistory")) { + if (!AppOptions.get("disableHistory")) { this.pdfHistory = new PDFHistory({ linkService: pdfLinkService, eventBus @@ -15362,4 +15371,4 @@ var __webpack_exports__PDFViewerApplicationConstants = __webpack_exports__.PDFVi var __webpack_exports__PDFViewerApplicationOptions = __webpack_exports__.PDFViewerApplicationOptions; export { __webpack_exports__PDFViewerApplication as PDFViewerApplication, __webpack_exports__PDFViewerApplicationConstants as PDFViewerApplicationConstants, __webpack_exports__PDFViewerApplicationOptions as PDFViewerApplicationOptions }; -//# sourceMappingURL=viewer.mjs.map \ No newline at end of file +//# sourceMappingURL=viewer.mjs.map diff --git a/patches/pdf.js.patch b/patches/pdf.js.patch index be199c9..bce930b 100644 --- a/patches/pdf.js.patch +++ b/patches/pdf.js.patch @@ -1,7 +1,30 @@ diff --git a/web/viewer.mjs b/web/viewer.mjs -index c3d794a..9df6c47 100644 +index c3d794a..79c64de 100644 --- a/web/viewer.mjs +++ b/web/viewer.mjs +@@ -6373,6 +6373,14 @@ class PDFHistory { + window.history.forward(); + } + } ++ get canGoBack() { ++ const state = window.history.state; ++ return this._initialized && !this._popStateInProgress && this.#isValidState(state) && state.uid > 0; ++ } ++ get canGoForward() { ++ const state = window.history.state; ++ return this._initialized && !this._popStateInProgress && this.#isValidState(state) && state.uid < this._maxUid; ++ } + get popStateInProgress() { + return this._initialized && (this._popStateInProgress || this._blockHashChange > 0); + } +@@ -6400,6 +6408,7 @@ class PDFHistory { + if (shouldReplace) { + window.history.replaceState(newState, "", newUrl); + } else { ++ this._maxUid = newState.uid; + window.history.pushState(newState, "", newUrl); + } + } @@ -13347,7 +13347,8 @@ const PDFViewerApplication = { const pdfRenderingQueue = new PDFRenderingQueue(); pdfRenderingQueue.onIdle = this._cleanup.bind(this); @@ -12,6 +35,15 @@ index c3d794a..9df6c47 100644 eventBus, externalLinkTarget: AppOptions.get("externalLinkTarget"), externalLinkRel: AppOptions.get("externalLinkRel"), +@@ -13429,7 +13438,7 @@ const PDFViewerApplication = { + }); + pdfRenderingQueue.setThumbnailViewer(this.pdfThumbnailViewer); + } +- if (!this.isViewerEmbedded && !AppOptions.get("disableHistory")) { ++ if (!AppOptions.get("disableHistory")) { + this.pdfHistory = new PDFHistory({ + linkService: pdfLinkService, + eventBus @@ -15362,4 +15363,25 @@ var __webpack_exports__PDFViewerApplicationConstants = __webpack_exports__.PDFVi var __webpack_exports__PDFViewerApplicationOptions = __webpack_exports__.PDFViewerApplicationOptions; export { __webpack_exports__PDFViewerApplication as PDFViewerApplication, __webpack_exports__PDFViewerApplicationConstants as PDFViewerApplicationConstants, __webpack_exports__PDFViewerApplicationOptions as PDFViewerApplicationOptions };