Support file save triggered from the Firefox integrated version.
Related to https://bugzilla.mozilla.org/show_bug.cgi?id=1659753 This allows Firefox trigger a "save" event from ctrl/cmd+s or the "Save Page As" context menu, which in turn lets pdf.js generate a new PDF if there is form data to save. I also now use `sourceEventType` on downloads so Firefox can determine if it should launch the "open with" dialog or "save as" dialog.
This commit is contained in:
		
							parent
							
								
									10f61b8c96
								
							
						
					
					
						commit
						8023175103
					
				| @ -2541,7 +2541,7 @@ class WorkerTransport { | |||||||
|         numPages: this._numPages, |         numPages: this._numPages, | ||||||
|         annotationStorage: |         annotationStorage: | ||||||
|           (annotationStorage && annotationStorage.getAll()) || null, |           (annotationStorage && annotationStorage.getAll()) || null, | ||||||
|         filename: this._fullReader.filename, |         filename: this._fullReader ? this._fullReader.filename : null, | ||||||
|       }) |       }) | ||||||
|       .finally(() => { |       .finally(() => { | ||||||
|         annotationStorage.resetModified(); |         annotationStorage.resetModified(); | ||||||
|  | |||||||
							
								
								
									
										26
									
								
								web/app.js
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								web/app.js
									
									
									
									
									
								
							| @ -874,7 +874,7 @@ const PDFViewerApplication = { | |||||||
|     ); |     ); | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   download() { |   download({ sourceEventType = "download" }) { | ||||||
|     function downloadByUrl() { |     function downloadByUrl() { | ||||||
|       downloadManager.downloadUrl(url, filename); |       downloadManager.downloadUrl(url, filename); | ||||||
|     } |     } | ||||||
| @ -902,12 +902,12 @@ const PDFViewerApplication = { | |||||||
|       .getData() |       .getData() | ||||||
|       .then(function (data) { |       .then(function (data) { | ||||||
|         const blob = new Blob([data], { type: "application/pdf" }); |         const blob = new Blob([data], { type: "application/pdf" }); | ||||||
|         downloadManager.download(blob, url, filename); |         downloadManager.download(blob, url, filename, sourceEventType); | ||||||
|       }) |       }) | ||||||
|       .catch(downloadByUrl); // Error occurred, try downloading with the URL.
 |       .catch(downloadByUrl); // Error occurred, try downloading with the URL.
 | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   save() { |   save({ sourceEventType = "download" }) { | ||||||
|     if (this._saveInProgress) { |     if (this._saveInProgress) { | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
| @ -927,7 +927,7 @@ const PDFViewerApplication = { | |||||||
|     // When the PDF document isn't ready, or the PDF file is still downloading,
 |     // When the PDF document isn't ready, or the PDF file is still downloading,
 | ||||||
|     // simply download using the URL.
 |     // simply download using the URL.
 | ||||||
|     if (!this.pdfDocument || !this.downloadComplete) { |     if (!this.pdfDocument || !this.downloadComplete) { | ||||||
|       this.download(); |       this.download({ sourceEventType }); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -936,10 +936,10 @@ const PDFViewerApplication = { | |||||||
|       .saveDocument(this.pdfDocument.annotationStorage) |       .saveDocument(this.pdfDocument.annotationStorage) | ||||||
|       .then(data => { |       .then(data => { | ||||||
|         const blob = new Blob([data], { type: "application/pdf" }); |         const blob = new Blob([data], { type: "application/pdf" }); | ||||||
|         downloadManager.download(blob, url, filename); |         downloadManager.download(blob, url, filename, sourceEventType); | ||||||
|       }) |       }) | ||||||
|       .catch(() => { |       .catch(() => { | ||||||
|         this.download(); |         this.download({ sourceEventType }); | ||||||
|       }) |       }) | ||||||
|       .finally(() => { |       .finally(() => { | ||||||
|         this._saveInProgress = false; |         this._saveInProgress = false; | ||||||
| @ -1722,6 +1722,7 @@ const PDFViewerApplication = { | |||||||
|     eventBus._on("presentationmode", webViewerPresentationMode); |     eventBus._on("presentationmode", webViewerPresentationMode); | ||||||
|     eventBus._on("print", webViewerPrint); |     eventBus._on("print", webViewerPrint); | ||||||
|     eventBus._on("download", webViewerDownload); |     eventBus._on("download", webViewerDownload); | ||||||
|  |     eventBus._on("save", webViewerSave); | ||||||
|     eventBus._on("firstpage", webViewerFirstPage); |     eventBus._on("firstpage", webViewerFirstPage); | ||||||
|     eventBus._on("lastpage", webViewerLastPage); |     eventBus._on("lastpage", webViewerLastPage); | ||||||
|     eventBus._on("nextpage", webViewerNextPage); |     eventBus._on("nextpage", webViewerNextPage); | ||||||
| @ -1800,6 +1801,7 @@ const PDFViewerApplication = { | |||||||
|     eventBus._off("presentationmode", webViewerPresentationMode); |     eventBus._off("presentationmode", webViewerPresentationMode); | ||||||
|     eventBus._off("print", webViewerPrint); |     eventBus._off("print", webViewerPrint); | ||||||
|     eventBus._off("download", webViewerDownload); |     eventBus._off("download", webViewerDownload); | ||||||
|  |     eventBus._off("save", webViewerSave); | ||||||
|     eventBus._off("firstpage", webViewerFirstPage); |     eventBus._off("firstpage", webViewerFirstPage); | ||||||
|     eventBus._off("lastpage", webViewerLastPage); |     eventBus._off("lastpage", webViewerLastPage); | ||||||
|     eventBus._off("nextpage", webViewerNextPage); |     eventBus._off("nextpage", webViewerNextPage); | ||||||
| @ -2334,16 +2336,22 @@ function webViewerPresentationMode() { | |||||||
| function webViewerPrint() { | function webViewerPrint() { | ||||||
|   window.print(); |   window.print(); | ||||||
| } | } | ||||||
| function webViewerDownload() { | function webViewerDownloadOrSave(sourceEventType) { | ||||||
|   if ( |   if ( | ||||||
|     PDFViewerApplication.pdfDocument && |     PDFViewerApplication.pdfDocument && | ||||||
|     PDFViewerApplication.pdfDocument.annotationStorage.size > 0 |     PDFViewerApplication.pdfDocument.annotationStorage.size > 0 | ||||||
|   ) { |   ) { | ||||||
|     PDFViewerApplication.save(); |     PDFViewerApplication.save({ sourceEventType }); | ||||||
|   } else { |   } else { | ||||||
|     PDFViewerApplication.download(); |     PDFViewerApplication.download({ sourceEventType }); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | function webViewerDownload() { | ||||||
|  |   webViewerDownloadOrSave("download"); | ||||||
|  | } | ||||||
|  | function webViewerSave() { | ||||||
|  |   webViewerDownloadOrSave("save"); | ||||||
|  | } | ||||||
| function webViewerFirstPage() { | function webViewerFirstPage() { | ||||||
|   if (PDFViewerApplication.pdfDocument) { |   if (PDFViewerApplication.pdfDocument) { | ||||||
|     PDFViewerApplication.page = 1; |     PDFViewerApplication.page = 1; | ||||||
|  | |||||||
| @ -64,7 +64,13 @@ class DownloadManager { | |||||||
|     download(blobUrl, filename); |     download(blobUrl, filename); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   download(blob, url, filename) { |   /** | ||||||
|  |    * @param sourceEventType {string} Used to signal what triggered the download. | ||||||
|  |    *   The version of PDF.js integrated with Firefox uses this to to determine | ||||||
|  |    *   which dialog to show. "save" triggers "save as" and "download" triggers | ||||||
|  |    *   the "open with" dialog. | ||||||
|  |    */ | ||||||
|  |   download(blob, url, filename, sourceEventType = "download") { | ||||||
|     if (navigator.msSaveBlob) { |     if (navigator.msSaveBlob) { | ||||||
|       // IE10 / IE11
 |       // IE10 / IE11
 | ||||||
|       if (!navigator.msSaveBlob(blob, filename)) { |       if (!navigator.msSaveBlob(blob, filename)) { | ||||||
|  | |||||||
| @ -115,7 +115,7 @@ class DownloadManager { | |||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   download(blob, url, filename) { |   download(blob, url, filename, sourceEventType = "download") { | ||||||
|     const blobUrl = URL.createObjectURL(blob); |     const blobUrl = URL.createObjectURL(blob); | ||||||
|     const onResponse = err => { |     const onResponse = err => { | ||||||
|       if (err && this.onerror) { |       if (err && this.onerror) { | ||||||
| @ -130,6 +130,7 @@ class DownloadManager { | |||||||
|         blobUrl, |         blobUrl, | ||||||
|         originalUrl: url, |         originalUrl: url, | ||||||
|         filename, |         filename, | ||||||
|  |         sourceEventType, | ||||||
|       }, |       }, | ||||||
|       onResponse |       onResponse | ||||||
|     ); |     ); | ||||||
| @ -231,6 +232,17 @@ class MozL10n { | |||||||
|   } |   } | ||||||
| })(); | })(); | ||||||
| 
 | 
 | ||||||
|  | (function listenSaveEvent() { | ||||||
|  |   const handleEvent = function ({ type, detail }) { | ||||||
|  |     if (!PDFViewerApplication.initialized) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |     PDFViewerApplication.eventBus.dispatch(type, { source: window }); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   window.addEventListener("save", handleEvent); | ||||||
|  | })(); | ||||||
|  | 
 | ||||||
| class FirefoxComDataRangeTransport extends PDFDataRangeTransport { | class FirefoxComDataRangeTransport extends PDFDataRangeTransport { | ||||||
|   requestDataRange(begin, end) { |   requestDataRange(begin, end) { | ||||||
|     FirefoxCom.request("requestDataRange", { begin, end }); |     FirefoxCom.request("requestDataRange", { begin, end }); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user