Bug 1292566 - The "open" button in the subview for uncommon and potentially unwanted downloads should not ask for confirmation. r?paolo
MozReview-Commit-ID: AVDyaQSbriX
--- a/browser/components/downloads/DownloadsViewUI.jsm
+++ b/browser/components/downloads/DownloadsViewUI.jsm
@@ -290,26 +290,35 @@ this.DownloadsViewUI.DownloadElementShel
*/
confirmUnblock(window, dialogType) {
DownloadsCommon.confirmUnblockDownload({
verdict: this.download.error.reputationCheckVerdict,
window,
dialogType,
}).then(action => {
if (action == "open") {
- return this.download.unblock().then(() => this.downloadsCmd_open());
+ return this.unblockAndOpenDownload();
} else if (action == "unblock") {
return this.download.unblock();
} else if (action == "confirmBlock") {
return this.download.confirmBlock();
}
}).catch(Cu.reportError);
},
/**
+ * Unblocks the downloaded file and opens it.
+ *
+ * @return A promise that's resolved after the file has been opened.
+ */
+ unblockAndOpenDownload() {
+ return this.download.unblock().then(() => this.downloadsCmd_open());
+ },
+
+ /**
* Returns the name of the default command to use for the current state of the
* download, when there is a double click or another default interaction. If
* there is no default command for the current state, returns an empty string.
* The commands are implemented as functions on this object or derived ones.
*/
get currentDefaultCommandName() {
switch (DownloadsCommon.stateOfDownload(this.download)) {
case Ci.nsIDownloadManager.DOWNLOAD_NOTSTARTED:
@@ -343,16 +352,17 @@ this.DownloadsViewUI.DownloadElementShel
case "downloadsCmd_pauseResume":
return this.download.hasPartialData && !this.download.error;
case "downloadsCmd_openReferrer":
return !!this.download.source.referrer;
case "downloadsCmd_confirmBlock":
case "downloadsCmd_chooseUnblock":
case "downloadsCmd_chooseOpen":
case "downloadsCmd_unblock":
+ case "downloadsCmd_unblockAndOpen":
return this.download.hasBlockedData;
}
return false;
},
downloadsCmd_cancel() {
// This is the correct way to avoid race conditions when cancelling.
this.download.cancel().catch(() => {});
--- a/browser/components/downloads/content/downloads.js
+++ b/browser/components/downloads/content/downloads.js
@@ -1108,19 +1108,19 @@ DownloadsViewItem.prototype = {
this.confirmUnblock(window, "unblock");
},
downloadsCmd_chooseUnblock() {
DownloadsPanel.hidePanel();
this.confirmUnblock(window, "chooseUnblock");
},
- downloadsCmd_chooseOpen() {
+ downloadsCmd_unblockAndOpen() {
DownloadsPanel.hidePanel();
- this.confirmUnblock(window, "chooseOpen");
+ this.unblockAndOpenDownload().catch(Cu.reportError);
},
downloadsCmd_open() {
this.download.launch().catch(Cu.reportError);
// We explicitly close the panel here to give the user the feedback that
// their click has been received, and we're handling the action.
// Otherwise, we'd have to wait for the file-type handler to execute
@@ -1195,17 +1195,17 @@ const DownloadsViewController = {
if (!(aCommand in this) &&
!(aCommand in DownloadsViewItem.prototype)) {
return false;
}
// The currently supported commands depend on whether the blocked subview is
// showing. If it is, then take the following path.
if (DownloadsBlockedSubview.view.showingSubView) {
let blockedSubviewCmds = [
- "downloadsCmd_chooseOpen",
+ "downloadsCmd_unblockAndOpen",
"cmd_delete",
];
return blockedSubviewCmds.indexOf(aCommand) >= 0;
}
// If the blocked subview is not showing, then determine if focus is on a
// control in the downloads list.
let element = document.commandDispatcher.focusedElement;
while (element && element != DownloadsView.richListBox) {
--- a/browser/components/downloads/content/downloadsOverlay.xul
+++ b/browser/components/downloads/content/downloadsOverlay.xul
@@ -20,18 +20,18 @@
<command id="downloadsCmd_pauseResume"
oncommand="goDoCommand('downloadsCmd_pauseResume')"/>
<command id="downloadsCmd_cancel"
oncommand="goDoCommand('downloadsCmd_cancel')"/>
<command id="downloadsCmd_unblock"
oncommand="goDoCommand('downloadsCmd_unblock')"/>
<command id="downloadsCmd_chooseUnblock"
oncommand="goDoCommand('downloadsCmd_chooseUnblock')"/>
- <command id="downloadsCmd_chooseOpen"
- oncommand="goDoCommand('downloadsCmd_chooseOpen')"/>
+ <command id="downloadsCmd_unblockAndOpen"
+ oncommand="goDoCommand('downloadsCmd_unblockAndOpen')"/>
<command id="downloadsCmd_confirmBlock"
oncommand="goDoCommand('downloadsCmd_confirmBlock')"/>
<command id="downloadsCmd_open"
oncommand="goDoCommand('downloadsCmd_open')"/>
<command id="downloadsCmd_show"
oncommand="goDoCommand('downloadsCmd_show')"/>
<command id="downloadsCmd_retry"
oncommand="goDoCommand('downloadsCmd_retry')"/>
@@ -163,17 +163,17 @@
<description id="downloadsPanel-blockedSubview-details1"/>
<description id="downloadsPanel-blockedSubview-details2"/>
<spacer flex="1"/>
<hbox id="downloadsPanel-blockedSubview-buttons"
class="downloadsPanelFooter"
align="stretch">
<button id="downloadsPanel-blockedSubview-openButton"
class="plain downloadsPanelFooterButton"
- command="downloadsCmd_chooseOpen"
+ command="downloadsCmd_unblockAndOpen"
flex="1"/>
<toolbarseparator/>
<button id="downloadsPanel-blockedSubview-deleteButton"
class="plain downloadsPanelFooterButton"
oncommand="DownloadsBlockedSubview.confirmBlock();"
default="true"
flex="1"/>
</hbox>
--- a/browser/components/downloads/test/browser/browser_downloads_panel_block.js
+++ b/browser/components/downloads/test/browser/browser_downloads_panel_block.js
@@ -31,22 +31,25 @@ add_task(function* mainTest() {
// back to it.
EventUtils.synthesizeMouse(DownloadsPanel.panel, 10, 10, {}, window);
yield promiseSubviewShown(false);
// Show the subview again.
EventUtils.sendMouseEvent({ type: "click" }, item);
yield promiseSubviewShown(true);
- // Click the Open button. The alert blocked-download dialog should be
- // shown.
- let dialogPromise = promiseAlertDialogOpen("cancel");
+ // Click the Open button. The download should be unblocked and then opened,
+ // i.e., unblockAndOpenDownload() should be called on the item. The panel
+ // should also be closed as a result, so wait for that too.
+ let unblockOpenPromise = promiseUnblockAndOpenDownloadCalled(item);
+ let hidePromise = promisePanelHidden();
EventUtils.synthesizeMouse(DownloadsBlockedSubview.elements.openButton,
10, 10, {}, window);
- yield dialogPromise;
+ yield unblockOpenPromise;
+ yield hidePromise;
window.focus();
yield SimpleTest.promiseFocus(window);
// Reopen the panel and show the subview again.
yield openPanel();
EventUtils.sendMouseEvent({ type: "click" }, item);
@@ -160,8 +163,21 @@ function promiseSubviewShown(shown) {
!DownloadsBlockedSubview.view._transitioning) {
clearInterval(interval);
setTimeout(resolve, 1000);
return;
}
}, 0);
});
}
+
+function promiseUnblockAndOpenDownloadCalled(item) {
+ return new Promise(resolve => {
+ let realFn = item._shell.unblockAndOpenDownload;
+ item._shell.unblockAndOpenDownload = () => {
+ item._shell.unblockAndOpenDownload = realFn;
+ resolve();
+ // unblockAndOpenDownload returns a promise (that's resolved when the file
+ // is opened).
+ return Promise.resolve();
+ };
+ });
+}