From 9745b75858d66f2fc0c6fe5e57d7bb9acdf8b3ca Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sun, 12 Sep 2021 12:34:58 +0200 Subject: [PATCH] [GENERIC viewer] Always show the Download-buttons, to allow saving of forms (issue 13997) Originally the library/viewer didn't support forms, and the hiding of the Download-buttons (when new documents are opened) didn't really matter all that much. Hence the simplest solution, at the time, was to hide the Download-buttons since we use the URL as a fallback when downloading data in the GENERIC `DownloadManager`. Nowadays we obviously want to support saving of forms in the GENERIC viewer, regardless of how the document was opened, which could thus *potentially* lead to the fallback download-URL being wrong. In order to be able to show the Download-buttons unconditionally, this patch slightly re-factors the viewer to track the download-URL *separately* to prevent any issues there. *Please note:* As mentioned in the issue, the ViewBookmark-buttons are specific to the initial URL when the viewer is first opened. Hence they (still) don't make sense when a new document has been opened, since it's then impossible to obtain a usable link to the *currently* active document. --- web/app.js | 40 +++++++++++++++++++++++++++------------- web/download_manager.js | 1 + 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/web/app.js b/web/app.js index b0d4be166..7c7a510cc 100644 --- a/web/app.js +++ b/web/app.js @@ -251,6 +251,7 @@ const PDFViewerApplication = { isViewerEmbedded: window.parent !== window, url: "", baseUrl: "", + _downloadUrl: "", externalServices: DefaultExternalServices, _boundEvents: Object.create(null), documentInfo: null, @@ -743,9 +744,13 @@ const PDFViewerApplication = { }); }, - setTitleUsingUrl(url = "") { + setTitleUsingUrl(url = "", downloadUrl = null) { this.url = url; this.baseUrl = url.split("#")[0]; + if (downloadUrl) { + this._downloadUrl = + downloadUrl === url ? this.baseUrl : downloadUrl.split("#")[0]; + } let title = getPdfFilenameFromUrl(url, ""); if (!title) { try { @@ -773,6 +778,16 @@ const PDFViewerApplication = { return this._contentDispositionFilename || getPdfFilenameFromUrl(this.url); }, + /** + * @private + */ + _hideViewBookmark() { + // URL does not reflect proper document location - hiding some buttons. + const { toolbar, secondaryToolbar } = this.appConfig; + toolbar.viewBookmark.hidden = true; + secondaryToolbar.viewBookmarkButton.hidden = true; + }, + /** * @private */ @@ -793,6 +808,7 @@ const PDFViewerApplication = { */ async close() { this._unblockDocumentLoadEvent(); + this._hideViewBookmark(); if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) { const { container } = this.appConfig.errorWrapper; @@ -835,6 +851,7 @@ const PDFViewerApplication = { this.downloadComplete = false; this.url = ""; this.baseUrl = ""; + this._downloadUrl = ""; this.documentInfo = null; this.metadata = null; this._contentDispositionFilename = null; @@ -883,13 +900,13 @@ const PDFViewerApplication = { const parameters = Object.create(null); if (typeof file === "string") { // URL - this.setTitleUsingUrl(file); + this.setTitleUsingUrl(file, /* downloadUrl = */ file); parameters.url = file; } else if (file && "byteLength" in file) { // ArrayBuffer parameters.data = file; } else if (file.url && file.originalUrl) { - this.setTitleUsingUrl(file.originalUrl); + this.setTitleUsingUrl(file.originalUrl, /* downloadUrl = */ file.url); parameters.url = file.url; } // Set the necessary API parameters, using the available options. @@ -965,7 +982,7 @@ const PDFViewerApplication = { }, async download({ sourceEventType = "download" } = {}) { - const url = this.baseUrl, + const url = this._downloadUrl, filename = this._docFilename; try { this._ensureDownloadComplete(); @@ -988,7 +1005,7 @@ const PDFViewerApplication = { this._saveInProgress = true; await this.pdfScriptingManager.dispatchWillSave(); - const url = this.baseUrl, + const url = this._downloadUrl, filename = this._docFilename; try { this._ensureDownloadComplete(); @@ -2261,13 +2278,17 @@ function webViewerOpenFileViaURL(file) { if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) { if (file) { PDFViewerApplication.open(file); + } else { + PDFViewerApplication._hideViewBookmark(); } } else if (PDFJSDev.test("MOZCENTRAL || CHROME")) { - PDFViewerApplication.setTitleUsingUrl(file); + PDFViewerApplication.setTitleUsingUrl(file, /* downloadUrl = */ file); PDFViewerApplication.initPassiveLoading(); } else { if (file) { throw new Error("Not implemented: webViewerOpenFileViaURL"); + } else { + PDFViewerApplication._hideViewBookmark(); } } } @@ -2487,13 +2508,6 @@ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) { }; fileReader.readAsArrayBuffer(file); } - - // URL does not reflect proper document location - hiding some icons. - const appConfig = PDFViewerApplication.appConfig; - appConfig.toolbar.viewBookmark.hidden = true; - appConfig.secondaryToolbar.viewBookmarkButton.hidden = true; - appConfig.toolbar.download.hidden = true; - appConfig.secondaryToolbar.downloadButton.hidden = true; }; webViewerOpenFile = function (evt) { diff --git a/web/download_manager.js b/web/download_manager.js index c57f71a14..a7a09a2b3 100644 --- a/web/download_manager.js +++ b/web/download_manager.js @@ -49,6 +49,7 @@ class DownloadManager { downloadUrl(url, filename) { if (!createValidAbsoluteUrl(url, "http://example.com")) { + console.error(`downloadUrl - not a valid URL: ${url}`); return; // restricted/invalid URL } download(url + "#pdfjs.action=download", filename);