Skip to content

Commit

Permalink
[GeckoView] Add a button to download and open the file in an external…
Browse files Browse the repository at this point in the history
… app (bug 1829367)
  • Loading branch information
calixteman committed May 5, 2023
1 parent f151a39 commit c7c19ad
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 11 deletions.
2 changes: 2 additions & 0 deletions l10n/en-US/viewer.properties
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ save.title=Save
save_label=Save
bookmark1.title=Current Page (View URL from Current Page)
bookmark1_label=Current Page
openinapp.title=Open in app
openinapp_label=Open in app

# Secondary toolbar and context menu
tools.title=Tools
Expand Down
25 changes: 19 additions & 6 deletions web/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -1012,7 +1012,7 @@ const PDFViewerApplication = {
throw new Error("PDF document not downloaded.");
},

async download() {
async download(options = {}) {
const url = this._downloadUrl,
filename = this._docFilename;
try {
Expand All @@ -1021,15 +1021,15 @@ const PDFViewerApplication = {
const data = await this.pdfDocument.getData();
const blob = new Blob([data], { type: "application/pdf" });

await this.downloadManager.download(blob, url, filename);
await this.downloadManager.download(blob, url, filename, options);
} 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);
await this.downloadManager.downloadUrl(url, filename, options);
}
},

async save() {
async save(options = {}) {
if (this._saveInProgress) {
return;
}
Expand All @@ -1044,12 +1044,12 @@ const PDFViewerApplication = {
const data = await this.pdfDocument.saveDocument();
const blob = new Blob([data], { type: "application/pdf" });

await this.downloadManager.download(blob, url, filename);
await this.downloadManager.download(blob, url, filename, options);
} catch (reason) {
// When the PDF document isn't ready, or the PDF file is still
// downloading, simply fallback to a "regular" download.
console.error(`Error when saving the document: ${reason.message}`);
await this.download();
await this.download(options);
} finally {
await this.pdfScriptingManager.dispatchDidSave();
this._saveInProgress = false;
Expand All @@ -1071,6 +1071,14 @@ const PDFViewerApplication = {
}
},

openInExternalApp() {
if (this.pdfDocument?.annotationStorage.size > 0) {
this.save({ openInExternalApp: true });
} else {
this.download({ openInExternalApp: true });
}
},

/**
* Report the error; used for errors affecting loading and/or parsing of
* the entire PDF document.
Expand Down Expand Up @@ -1852,6 +1860,7 @@ const PDFViewerApplication = {
);
eventBus._on("print", webViewerPrint);
eventBus._on("download", webViewerDownload);
eventBus._on("openinexternalapp", webViewerOpenInExternalApp);
eventBus._on("firstpage", webViewerFirstPage);
eventBus._on("lastpage", webViewerLastPage);
eventBus._on("nextpage", webViewerNextPage);
Expand Down Expand Up @@ -1984,6 +1993,7 @@ const PDFViewerApplication = {
eventBus._off("presentationmode", webViewerPresentationMode);
eventBus._off("print", webViewerPrint);
eventBus._off("download", webViewerDownload);
eventBus._off("openinexternalapp", webViewerOpenInExternalApp);
eventBus._off("firstpage", webViewerFirstPage);
eventBus._off("lastpage", webViewerLastPage);
eventBus._off("nextpage", webViewerNextPage);
Expand Down Expand Up @@ -2500,6 +2510,9 @@ function webViewerPrint() {
function webViewerDownload() {
PDFViewerApplication.downloadOrSave();
}
function webViewerOpenInExternalApp() {
PDFViewerApplication.openInExternalApp();
}
function webViewerFirstPage() {
PDFViewerApplication.page = 1;
}
Expand Down
4 changes: 2 additions & 2 deletions web/download_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function download(blobUrl, filename) {
class DownloadManager {
#openBlobUrls = new WeakMap();

downloadUrl(url, filename) {
downloadUrl(url, filename, _options) {
if (!createValidAbsoluteUrl(url, "http://example.com")) {
console.error(`downloadUrl - not a valid URL: ${url}`);
return; // restricted/invalid URL
Expand Down Expand Up @@ -110,7 +110,7 @@ class DownloadManager {
return false;
}

download(blob, url, filename) {
download(blob, url, filename, _options) {
const blobUrl = URL.createObjectURL(blob);
download(blobUrl, filename);
}
Expand Down
6 changes: 4 additions & 2 deletions web/firefoxcom.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,11 @@ class FirefoxCom {
class DownloadManager {
#openBlobUrls = new WeakMap();

downloadUrl(url, filename) {
downloadUrl(url, filename, options) {
FirefoxCom.request("download", {
originalUrl: url,
filename,
options,
});
}

Expand Down Expand Up @@ -160,13 +161,14 @@ class DownloadManager {
return false;
}

download(blob, url, filename) {
download(blob, url, filename, options) {
const blobUrl = URL.createObjectURL(blob);

FirefoxCom.request("download", {
blobUrl,
originalUrl: url,
filename,
options,
});
}
}
Expand Down
11 changes: 11 additions & 0 deletions web/images/gv-toolbarButton-openinapp.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion web/toolbar-geckoview.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ class Toolbar {
*/
constructor(options, eventBus, _l10n) {
this.#eventBus = eventBus;
this.#buttons = [{ element: options.download, eventName: "download" }];
this.#buttons = [
{ element: options.download, eventName: "download" },
{ element: options.openInApp, eventName: "openinexternalapp" },
];

// Bind the event listeners for click and various other actions.
this.#bindListeners(options);
Expand Down
5 changes: 5 additions & 0 deletions web/viewer-geckoview.css
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
--toolbar-fg-color: #15141a;

--toolbarButton-download-icon: url(images/gv-toolbarButton-download.svg);
--toolbarButton-openinapp-icon: url(images/gv-toolbarButton-openinapp.svg);
}

:root:dir(rtl) {
Expand Down Expand Up @@ -217,6 +218,10 @@ body {
mask-image: var(--toolbarButton-download-icon);
}

#openinapp::before {
mask-image: var(--toolbarButton-openinapp-icon);
}

.dialogButton {
width: auto;
margin: 3px 4px 2px !important;
Expand Down
3 changes: 3 additions & 0 deletions web/viewer-geckoview.html
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@
<button id="download" class="toolbarButton" title="Save" tabindex="31" data-l10n-id="download">
<span data-l10n-id="download_label">Download</span>
</button>
<button id="openinapp" class="toolbarButton" title="Open in app" tabindex="32" data-l10n-id="openinapp">
<span data-l10n-id="open_in_app_label">Open in app</span>
</button>
</div>

<div id="viewerContainer" tabindex="0">
Expand Down
1 change: 1 addition & 0 deletions web/viewer-geckoview.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ function getViewerConfiguration() {
mainContainer,
container: document.getElementById("floatingToolbar"),
download: document.getElementById("download"),
openInApp: document.getElementById("openinapp"),
},

passwordOverlay: {
Expand Down

0 comments on commit c7c19ad

Please sign in to comment.