Merge pull request #13175 from Snuffleupagus/app-close-save

[GENERIC viewer] Avoid data loss in forms, by triggering saving when the document is closed (issue 12257)
This commit is contained in:
Tim van der Meij 2021-04-05 14:03:18 +02:00 committed by GitHub
commit 3698bc1287
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -802,7 +802,19 @@ const PDFViewerApplication = {
} }
if (!this.pdfLoadingTask) { if (!this.pdfLoadingTask) {
return undefined; return;
}
if (
(typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) &&
this.pdfDocument?.annotationStorage.size > 0 &&
this._annotationStorageModified
) {
try {
// Trigger saving, to prevent data loss in forms; see issue 12257.
await this.save({ sourceEventType: "save" });
} catch (reason) {
// Ignoring errors, to ensure that document closing won't break.
}
} }
const promises = []; const promises = [];
@ -851,8 +863,6 @@ const PDFViewerApplication = {
PDFBug.cleanup(); PDFBug.cleanup();
} }
await Promise.all(promises); await Promise.all(promises);
return undefined;
}, },
/** /**
@ -949,62 +959,59 @@ const PDFViewerApplication = {
); );
}, },
download({ sourceEventType = "download" } = {}) { /**
function downloadByUrl() { * @private
downloadManager.downloadUrl(url, filename); */
} _ensureDownloadComplete() {
if (this.pdfDocument && this.downloadComplete) {
const downloadManager = this.downloadManager,
url = this.baseUrl,
filename = this._docFilename;
// When the PDF document isn't ready, or the PDF file is still downloading,
// simply download using the URL.
if (!this.pdfDocument || !this.downloadComplete) {
downloadByUrl();
return; return;
} }
throw new Error("PDF document not downloaded.");
},
this.pdfDocument async download({ sourceEventType = "download" } = {}) {
.getData() const url = this.baseUrl,
.then(function (data) { filename = this._docFilename;
const blob = new Blob([data], { type: "application/pdf" }); try {
downloadManager.download(blob, url, filename, sourceEventType); this._ensureDownloadComplete();
})
.catch(downloadByUrl); // Error occurred, try downloading with the URL. const data = await this.pdfDocument.getData();
const blob = new Blob([data], { type: "application/pdf" });
await this.downloadManager.download(blob, url, filename, sourceEventType);
} catch (reason) {
// When the PDF document isn't ready, or the PDF file is still
// downloading, simply download using the URL.
await this.downloadManager.downloadUrl(url, filename);
}
}, },
async save({ sourceEventType = "download" } = {}) { async save({ sourceEventType = "download" } = {}) {
if (this._saveInProgress) { if (this._saveInProgress) {
return; return;
} }
const downloadManager = this.downloadManager,
url = this.baseUrl,
filename = this._docFilename;
// When the PDF document isn't ready, or the PDF file is still downloading,
// simply download using the URL.
if (!this.pdfDocument || !this.downloadComplete) {
this.download({ sourceEventType });
return;
}
this._saveInProgress = true; this._saveInProgress = true;
await this.pdfScriptingManager.dispatchWillSave(); await this.pdfScriptingManager.dispatchWillSave();
this.pdfDocument const url = this.baseUrl,
.saveDocument(this.pdfDocument.annotationStorage) filename = this._docFilename;
.then(data => { try {
const blob = new Blob([data], { type: "application/pdf" }); this._ensureDownloadComplete();
downloadManager.download(blob, url, filename, sourceEventType);
}) const data = await this.pdfDocument.saveDocument(
.catch(() => { this.pdfDocument.annotationStorage
this.download({ sourceEventType }); );
}) const blob = new Blob([data], { type: "application/pdf" });
.finally(async () => {
await this.pdfScriptingManager.dispatchDidSave(); await this.downloadManager.download(blob, url, filename, sourceEventType);
this._saveInProgress = false; } catch (reason) {
}); // When the PDF document isn't ready, or the PDF file is still
// downloading, simply fallback to a "regular" download.
await this.download({ sourceEventType });
} finally {
await this.pdfScriptingManager.dispatchDidSave();
this._saveInProgress = false;
}
}, },
downloadOrSave(options) { downloadOrSave(options) {
@ -1710,11 +1717,19 @@ const PDFViewerApplication = {
} }
const { annotationStorage } = pdfDocument; const { annotationStorage } = pdfDocument;
annotationStorage.onSetModified = function () { annotationStorage.onSetModified = () => {
window.addEventListener("beforeunload", beforeUnload); window.addEventListener("beforeunload", beforeUnload);
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
this._annotationStorageModified = true;
}
}; };
annotationStorage.onResetModified = function () { annotationStorage.onResetModified = () => {
window.removeEventListener("beforeunload", beforeUnload); window.removeEventListener("beforeunload", beforeUnload);
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
delete this._annotationStorageModified;
}
}; };
}, },