[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.
This commit is contained in:
Jonas Jenwald 2021-09-12 12:34:58 +02:00
parent 95435ed66f
commit 9745b75858
2 changed files with 28 additions and 13 deletions

View File

@ -251,6 +251,7 @@ const PDFViewerApplication = {
isViewerEmbedded: window.parent !== window, isViewerEmbedded: window.parent !== window,
url: "", url: "",
baseUrl: "", baseUrl: "",
_downloadUrl: "",
externalServices: DefaultExternalServices, externalServices: DefaultExternalServices,
_boundEvents: Object.create(null), _boundEvents: Object.create(null),
documentInfo: null, documentInfo: null,
@ -743,9 +744,13 @@ const PDFViewerApplication = {
}); });
}, },
setTitleUsingUrl(url = "") { setTitleUsingUrl(url = "", downloadUrl = null) {
this.url = url; this.url = url;
this.baseUrl = url.split("#")[0]; this.baseUrl = url.split("#")[0];
if (downloadUrl) {
this._downloadUrl =
downloadUrl === url ? this.baseUrl : downloadUrl.split("#")[0];
}
let title = getPdfFilenameFromUrl(url, ""); let title = getPdfFilenameFromUrl(url, "");
if (!title) { if (!title) {
try { try {
@ -773,6 +778,16 @@ const PDFViewerApplication = {
return this._contentDispositionFilename || getPdfFilenameFromUrl(this.url); 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 * @private
*/ */
@ -793,6 +808,7 @@ const PDFViewerApplication = {
*/ */
async close() { async close() {
this._unblockDocumentLoadEvent(); this._unblockDocumentLoadEvent();
this._hideViewBookmark();
if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) { if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
const { container } = this.appConfig.errorWrapper; const { container } = this.appConfig.errorWrapper;
@ -835,6 +851,7 @@ const PDFViewerApplication = {
this.downloadComplete = false; this.downloadComplete = false;
this.url = ""; this.url = "";
this.baseUrl = ""; this.baseUrl = "";
this._downloadUrl = "";
this.documentInfo = null; this.documentInfo = null;
this.metadata = null; this.metadata = null;
this._contentDispositionFilename = null; this._contentDispositionFilename = null;
@ -883,13 +900,13 @@ const PDFViewerApplication = {
const parameters = Object.create(null); const parameters = Object.create(null);
if (typeof file === "string") { if (typeof file === "string") {
// URL // URL
this.setTitleUsingUrl(file); this.setTitleUsingUrl(file, /* downloadUrl = */ file);
parameters.url = file; parameters.url = file;
} else if (file && "byteLength" in file) { } else if (file && "byteLength" in file) {
// ArrayBuffer // ArrayBuffer
parameters.data = file; parameters.data = file;
} else if (file.url && file.originalUrl) { } else if (file.url && file.originalUrl) {
this.setTitleUsingUrl(file.originalUrl); this.setTitleUsingUrl(file.originalUrl, /* downloadUrl = */ file.url);
parameters.url = file.url; parameters.url = file.url;
} }
// Set the necessary API parameters, using the available options. // Set the necessary API parameters, using the available options.
@ -965,7 +982,7 @@ const PDFViewerApplication = {
}, },
async download({ sourceEventType = "download" } = {}) { async download({ sourceEventType = "download" } = {}) {
const url = this.baseUrl, const url = this._downloadUrl,
filename = this._docFilename; filename = this._docFilename;
try { try {
this._ensureDownloadComplete(); this._ensureDownloadComplete();
@ -988,7 +1005,7 @@ const PDFViewerApplication = {
this._saveInProgress = true; this._saveInProgress = true;
await this.pdfScriptingManager.dispatchWillSave(); await this.pdfScriptingManager.dispatchWillSave();
const url = this.baseUrl, const url = this._downloadUrl,
filename = this._docFilename; filename = this._docFilename;
try { try {
this._ensureDownloadComplete(); this._ensureDownloadComplete();
@ -2261,13 +2278,17 @@ function webViewerOpenFileViaURL(file) {
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) { if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
if (file) { if (file) {
PDFViewerApplication.open(file); PDFViewerApplication.open(file);
} else {
PDFViewerApplication._hideViewBookmark();
} }
} else if (PDFJSDev.test("MOZCENTRAL || CHROME")) { } else if (PDFJSDev.test("MOZCENTRAL || CHROME")) {
PDFViewerApplication.setTitleUsingUrl(file); PDFViewerApplication.setTitleUsingUrl(file, /* downloadUrl = */ file);
PDFViewerApplication.initPassiveLoading(); PDFViewerApplication.initPassiveLoading();
} else { } else {
if (file) { if (file) {
throw new Error("Not implemented: webViewerOpenFileViaURL"); throw new Error("Not implemented: webViewerOpenFileViaURL");
} else {
PDFViewerApplication._hideViewBookmark();
} }
} }
} }
@ -2487,13 +2508,6 @@ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
}; };
fileReader.readAsArrayBuffer(file); 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) { webViewerOpenFile = function (evt) {

View File

@ -49,6 +49,7 @@ class DownloadManager {
downloadUrl(url, filename) { downloadUrl(url, filename) {
if (!createValidAbsoluteUrl(url, "http://example.com")) { if (!createValidAbsoluteUrl(url, "http://example.com")) {
console.error(`downloadUrl - not a valid URL: ${url}`);
return; // restricted/invalid URL return; // restricted/invalid URL
} }
download(url + "#pdfjs.action=download", filename); download(url + "#pdfjs.action=download", filename);