зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1639069 - Add download context menu items to 'Use' and 'Always use' the system viewer to open the download. r=jaws
Differential Revision: https://phabricator.services.mozilla.com/D79396
This commit is contained in:
Родитель
1c447df70b
Коммит
394b51b9e3
|
@ -359,6 +359,13 @@ pref("browser.download.animateNotifications", true);
|
|||
// This records whether or not the panel has been shown at least once.
|
||||
pref("browser.download.panel.shown", false);
|
||||
|
||||
// This records whether or not to show the 'Open in system viewer' context menu item when appropriate
|
||||
pref("browser.download.openInSystemViewerContextMenuItem", true);
|
||||
|
||||
// This records whether or not to show the 'Always open...' context menu item when appropriate
|
||||
pref("browser.download.alwaysOpenInSystemViewerContextMenuItem", true);
|
||||
|
||||
|
||||
// This controls whether the button is automatically shown/hidden depending
|
||||
// on whether there are downloads to show.
|
||||
pref("browser.download.autohideButton", true);
|
||||
|
|
|
@ -229,6 +229,8 @@ var PrefObserver = {
|
|||
PrefObserver.register({
|
||||
// prefName: defaultValue
|
||||
animateNotifications: true,
|
||||
openInSystemViewerContextMenuItem: true,
|
||||
alwaysOpenInSystemViewerContextMenuItem: true,
|
||||
});
|
||||
|
||||
// DownloadsCommon
|
||||
|
@ -296,6 +298,20 @@ var DownloadsCommon = {
|
|||
return PrefObserver.animateNotifications;
|
||||
},
|
||||
|
||||
/**
|
||||
* Indicates whether or not to show the 'Open in system viewer' context menu item when appropriate
|
||||
*/
|
||||
get openInSystemViewerItemEnabled() {
|
||||
return PrefObserver.openInSystemViewerContextMenuItem;
|
||||
},
|
||||
|
||||
/**
|
||||
* Indicates whether or not to show the 'Always open...' context menu item when appropriate
|
||||
*/
|
||||
get alwaysOpenInSystemViewerItemEnabled() {
|
||||
return PrefObserver.alwaysOpenInSystemViewerContextMenuItem;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get access to one of the DownloadsData, PrivateDownloadsData, or
|
||||
* HistoryDownloadsData objects, depending on the privacy status of the
|
||||
|
@ -610,6 +626,9 @@ var DownloadsCommon = {
|
|||
* @param options.openWhere
|
||||
* Optional string indicating how to handle opening a download target file URI.
|
||||
* One of "window", "tab", "tabshifted".
|
||||
* @param options.useSystemDefault
|
||||
* Optional value indicating how to handle launching this download,
|
||||
* this call only. Will override the associated mimeInfo.preferredAction
|
||||
* @return {Promise}
|
||||
* @resolves When the instruction to launch the file has been
|
||||
* successfully given to the operating system or handled internally
|
||||
|
|
|
@ -297,6 +297,11 @@ class DownloadsSubview extends DownloadsViewUI.BaseView {
|
|||
while (!button._shell) {
|
||||
button = button.parentNode;
|
||||
}
|
||||
let download = button._shell.download;
|
||||
let { preferredAction, useSystemDefault } = DownloadsCommon.getMimeInfo(
|
||||
download
|
||||
);
|
||||
|
||||
menu.setAttribute("state", button.getAttribute("state"));
|
||||
if (button.hasAttribute("exists")) {
|
||||
menu.setAttribute("exists", button.getAttribute("exists"));
|
||||
|
@ -307,6 +312,37 @@ class DownloadsSubview extends DownloadsViewUI.BaseView {
|
|||
"temporary-block",
|
||||
button.classList.contains("temporary-block")
|
||||
);
|
||||
// menu items are conditionally displayed via CSS based on an is-pdf attribute
|
||||
DownloadsCommon.log(
|
||||
"DownloadsSubview, updateContextMenu, download is pdf? ",
|
||||
download.target.path,
|
||||
button.hasAttribute("is-pdf")
|
||||
);
|
||||
if (button.hasAttribute("is-pdf")) {
|
||||
menu.setAttribute("is-pdf", "true");
|
||||
let alwaysUseSystemViewerItem = menu.querySelector(
|
||||
".downloadAlwaysUseSystemDefaultMenuItem"
|
||||
);
|
||||
if (preferredAction === useSystemDefault) {
|
||||
alwaysUseSystemViewerItem.setAttribute("checked", "true");
|
||||
} else {
|
||||
alwaysUseSystemViewerItem.removeAttribute("checked");
|
||||
}
|
||||
alwaysUseSystemViewerItem.toggleAttribute(
|
||||
"enabled",
|
||||
DownloadsCommon.alwaysOpenInSystemViewerItemEnabled
|
||||
);
|
||||
let useSystemViewerItem = menu.querySelector(
|
||||
".downloadUseSystemDefaultMenuItem"
|
||||
);
|
||||
useSystemViewerItem.toggleAttribute(
|
||||
"enabled",
|
||||
DownloadsCommon.openInSystemViewerItemEnabled
|
||||
);
|
||||
} else {
|
||||
menu.removeAttribute("is-pdf");
|
||||
}
|
||||
|
||||
for (let menuitem of menu.getElementsByTagName("menuitem")) {
|
||||
let command = menuitem.getAttribute("command");
|
||||
if (!command) {
|
||||
|
|
|
@ -24,6 +24,13 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
OS: "resource://gre/modules/osfile.jsm",
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(
|
||||
this,
|
||||
"handlerSvc",
|
||||
"@mozilla.org/uriloader/handler-service;1",
|
||||
"nsIHandlerService"
|
||||
);
|
||||
|
||||
const HTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
|
||||
var gDownloadElementButtons = {
|
||||
|
@ -457,9 +464,21 @@ DownloadsViewUI.DownloadElementShell.prototype = {
|
|||
// on other properties. The order in which we check the properties of the
|
||||
// Download object is the same used by stateOfDownload.
|
||||
if (this.download.succeeded) {
|
||||
DownloadsCommon.log(
|
||||
"_updateStateInner, target exists? ",
|
||||
this.download.target.path,
|
||||
this.download.target.exists
|
||||
);
|
||||
if (this.download.target.exists) {
|
||||
// This is a completed download, and the target file still exists.
|
||||
this.element.setAttribute("exists", "true");
|
||||
|
||||
const isPDF = DownloadsCommon.isFileOfType(
|
||||
this.download,
|
||||
"application/pdf"
|
||||
);
|
||||
this.element.toggleAttribute("is-pdf", isPDF);
|
||||
|
||||
let sizeWithUnits = DownloadsViewUI.getSizeWithUnits(this.download);
|
||||
if (this.isPanel) {
|
||||
// In the Downloads Panel, we show the file size after the state
|
||||
|
@ -728,6 +747,9 @@ DownloadsViewUI.DownloadElementShell.prototype = {
|
|||
case "cmd_delete":
|
||||
// We don't want in-progress downloads to be removed accidentally.
|
||||
return this.download.stopped;
|
||||
case "downloadsCmd_openInSystemViewer":
|
||||
case "downloadsCmd_alwaysOpenInSystemViewer":
|
||||
return DownloadsCommon.isFileOfType(this.download, "application/pdf");
|
||||
}
|
||||
return DownloadsViewUI.isCommandName(aCommand) && !!this[aCommand];
|
||||
},
|
||||
|
@ -807,4 +829,39 @@ DownloadsViewUI.DownloadElementShell.prototype = {
|
|||
cmd_delete() {
|
||||
DownloadsCommon.deleteDownload(this.download).catch(Cu.reportError);
|
||||
},
|
||||
|
||||
downloadsCmd_openInSystemViewer() {
|
||||
// For this interaction only, pass a flag to override the preferredAction for this
|
||||
// mime-type and open using the system viewer
|
||||
DownloadsCommon.openDownload(this.download, {
|
||||
useSystemDefault: true,
|
||||
}).catch(Cu.reportError);
|
||||
},
|
||||
|
||||
downloadsCmd_alwaysOpenInSystemViewer() {
|
||||
// this command toggles between setting preferredAction for this mime-type to open
|
||||
// using the system viewer, or to open the file in browser.
|
||||
const mimeInfo = DownloadsCommon.getMimeInfo(this.download);
|
||||
if (mimeInfo.preferredAction !== mimeInfo.useSystemDefault) {
|
||||
// User has selected to open this mime-type with the system viewer from now on
|
||||
DownloadsCommon.log(
|
||||
"downloadsCmd_alwaysOpenInSystemViewer command for download: ",
|
||||
this.download,
|
||||
"switching to use system default for " + mimeInfo.type
|
||||
);
|
||||
mimeInfo.preferredAction = mimeInfo.useSystemDefault;
|
||||
mimeInfo.alwaysAskBeforeHandling = false;
|
||||
} else {
|
||||
DownloadsCommon.log(
|
||||
"downloadsCmd_alwaysOpenInSystemViewer command for download: ",
|
||||
this.download,
|
||||
"currently uses system default, switching to handleInternally"
|
||||
);
|
||||
// User has selected to not open this mime-type with the system viewer
|
||||
mimeInfo.preferredAction = mimeInfo.handleInternally;
|
||||
mimeInfo.alwaysAskBeforeHandling = true;
|
||||
}
|
||||
handlerSvc.store(mimeInfo);
|
||||
DownloadsCommon.openDownload(this.download).catch(Cu.reportError);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -705,6 +705,9 @@ DownloadsPlacesView.prototype = {
|
|||
// Set the state attribute so that only the appropriate items are displayed.
|
||||
let contextMenu = document.getElementById("downloadsContextMenu");
|
||||
let download = element._shell.download;
|
||||
let { preferredAction, useSystemDefault } = DownloadsCommon.getMimeInfo(
|
||||
download
|
||||
);
|
||||
contextMenu.setAttribute(
|
||||
"state",
|
||||
DownloadsCommon.stateOfDownload(download)
|
||||
|
@ -712,6 +715,31 @@ DownloadsPlacesView.prototype = {
|
|||
contextMenu.setAttribute("exists", "true");
|
||||
contextMenu.classList.toggle("temporary-block", !!download.hasBlockedData);
|
||||
|
||||
if (element.hasAttribute("is-pdf")) {
|
||||
contextMenu.setAttribute("is-pdf", "true");
|
||||
let alwaysUseSystemViewerItem = contextMenu.querySelector(
|
||||
".downloadAlwaysUseSystemDefaultMenuItem"
|
||||
);
|
||||
if (preferredAction === useSystemDefault) {
|
||||
alwaysUseSystemViewerItem.setAttribute("checked", "true");
|
||||
} else {
|
||||
alwaysUseSystemViewerItem.removeAttribute("checked");
|
||||
}
|
||||
alwaysUseSystemViewerItem.toggleAttribute(
|
||||
"enabled",
|
||||
DownloadsCommon.alwaysOpenInSystemViewerItemEnabled
|
||||
);
|
||||
let useSystemViewerItem = contextMenu.querySelector(
|
||||
".downloadUseSystemDefaultMenuItem"
|
||||
);
|
||||
useSystemViewerItem.toggleAttribute(
|
||||
"enabled",
|
||||
DownloadsCommon.openInSystemViewerItemEnabled
|
||||
);
|
||||
} else {
|
||||
contextMenu.removeAttribute("is-pdf");
|
||||
}
|
||||
|
||||
if (!download.stopped) {
|
||||
// The hasPartialData property of a download may change at any time after
|
||||
// it has started, so ensure we update the related command now.
|
||||
|
|
|
@ -95,8 +95,14 @@
|
|||
.download-state[state="1"]:not([exists])
|
||||
.downloadCommandsSeparator,
|
||||
.download-state[state="8"]:not(.temporary-block)
|
||||
.downloadCommandsSeparator
|
||||
.downloadCommandsSeparator,
|
||||
|
||||
/* the system-viewer context menu items are only shown for certain mime-types
|
||||
and can be individually enabled via prefs */
|
||||
.download-state:not([is-pdf]) .downloadUseSystemDefaultMenuItem,
|
||||
.download-state .downloadUseSystemDefaultMenuItem:not([enabled]),
|
||||
.download-state .downloadAlwaysUseSystemDefaultMenuItem:not([enabled]),
|
||||
.download-state:not([is-pdf]) .downloadAlwaysUseSystemDefaultMenuItem
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -937,6 +937,11 @@ var DownloadsView = {
|
|||
|
||||
DownloadsViewController.updateCommands();
|
||||
|
||||
let download = element._shell.download;
|
||||
let { preferredAction, useSystemDefault } = DownloadsCommon.getMimeInfo(
|
||||
download
|
||||
);
|
||||
|
||||
// Set the state attribute so that only the appropriate items are displayed.
|
||||
let contextMenu = document.getElementById("downloadsContextMenu");
|
||||
contextMenu.setAttribute("state", element.getAttribute("state"));
|
||||
|
@ -949,6 +954,30 @@ var DownloadsView = {
|
|||
"temporary-block",
|
||||
element.classList.contains("temporary-block")
|
||||
);
|
||||
if (element.hasAttribute("is-pdf")) {
|
||||
contextMenu.setAttribute("is-pdf", "true");
|
||||
let alwaysUseSystemViewerItem = contextMenu.querySelector(
|
||||
".downloadAlwaysUseSystemDefaultMenuItem"
|
||||
);
|
||||
if (preferredAction === useSystemDefault) {
|
||||
alwaysUseSystemViewerItem.setAttribute("checked", "true");
|
||||
} else {
|
||||
alwaysUseSystemViewerItem.removeAttribute("checked");
|
||||
}
|
||||
alwaysUseSystemViewerItem.toggleAttribute(
|
||||
"enabled",
|
||||
DownloadsCommon.alwaysOpenInSystemViewerItemEnabled
|
||||
);
|
||||
let useSystemViewerItem = contextMenu.querySelector(
|
||||
".downloadUseSystemDefaultMenuItem"
|
||||
);
|
||||
useSystemViewerItem.toggleAttribute(
|
||||
"enabled",
|
||||
DownloadsCommon.openInSystemViewerItemEnabled
|
||||
);
|
||||
} else {
|
||||
contextMenu.removeAttribute("is-pdf");
|
||||
}
|
||||
},
|
||||
|
||||
onDownloadDragStart(aEvent) {
|
||||
|
@ -1093,6 +1122,22 @@ class DownloadsViewItem extends DownloadsViewUI.DownloadElementShell {
|
|||
DownloadsPanel.hidePanel();
|
||||
}
|
||||
|
||||
downloadsCmd_openInSystemViewer() {
|
||||
super.downloadsCmd_openInSystemViewer();
|
||||
|
||||
// We explicitly close the panel here to give the user the feedback that
|
||||
// their click has been received, and we're handling the action.
|
||||
DownloadsPanel.hidePanel();
|
||||
}
|
||||
|
||||
downloadsCmd_alwaysOpenInSystemViewer() {
|
||||
super.downloadsCmd_alwaysOpenInSystemViewer();
|
||||
|
||||
// We explicitly close the panel here to give the user the feedback that
|
||||
// their click has been received, and we're handling the action.
|
||||
DownloadsPanel.hidePanel();
|
||||
}
|
||||
|
||||
downloadsCmd_show() {
|
||||
let file = new FileUtils.File(this.download.target.path);
|
||||
DownloadsCommon.showDownloadedFile(file);
|
||||
|
|
|
@ -22,4 +22,6 @@
|
|||
<command id="downloadsCmd_retry"/>
|
||||
<command id="downloadsCmd_openReferrer"/>
|
||||
<command id="downloadsCmd_clearDownloads"/>
|
||||
<command id="downloadsCmd_openInSystemViewer"/>
|
||||
<command id="downloadsCmd_alwaysOpenInSystemViewer"/>
|
||||
</commandset>
|
||||
|
|
|
@ -17,6 +17,13 @@
|
|||
<menuitem command="downloadsCmd_unblock"
|
||||
class="downloadUnblockMenuItem"
|
||||
data-l10n-id="downloads-cmd-unblock"/>
|
||||
<menuitem command="downloadsCmd_openInSystemViewer"
|
||||
class="downloadUseSystemDefaultMenuItem"
|
||||
data-l10n-id="downloads-cmd-use-system-default"/>
|
||||
<menuitem command="downloadsCmd_alwaysOpenInSystemViewer"
|
||||
type="checkbox"
|
||||
class="downloadAlwaysUseSystemDefaultMenuItem"
|
||||
data-l10n-id="downloads-cmd-always-use-system-default"/>
|
||||
<menuitem command="downloadsCmd_show"
|
||||
class="downloadShowMenuItem"
|
||||
#ifdef XP_MACOSX
|
||||
|
|
|
@ -38,6 +38,10 @@
|
|||
oncommand="goDoCommand('downloadsCmd_copyLocation')"/>
|
||||
<command id="downloadsCmd_clearList"
|
||||
oncommand="goDoCommand('downloadsCmd_clearList')"/>
|
||||
<command id="downloadsCmd_openInSystemViewer"
|
||||
oncommand="goDoCommand('downloadsCmd_openInSystemViewer')"/>
|
||||
<command id="downloadsCmd_alwaysOpenInSystemViewer"
|
||||
oncommand="goDoCommand('downloadsCmd_alwaysOpenInSystemViewer')"/>
|
||||
</commandset>
|
||||
|
||||
<!-- The panel has level="top" to ensure that it is never hidden by the
|
||||
|
@ -75,6 +79,13 @@
|
|||
<menuitem command="downloadsCmd_unblock"
|
||||
class="downloadUnblockMenuItem"
|
||||
data-l10n-id="downloads-cmd-unblock"/>
|
||||
<menuitem command="downloadsCmd_openInSystemViewer"
|
||||
class="downloadUseSystemDefaultMenuItem"
|
||||
data-l10n-id="downloads-cmd-use-system-default"/>
|
||||
<menuitem command="downloadsCmd_alwaysOpenInSystemViewer"
|
||||
type="checkbox"
|
||||
class="downloadAlwaysUseSystemDefaultMenuItem"
|
||||
data-l10n-id="downloads-cmd-always-use-system-default"/>
|
||||
<menuitem command="downloadsCmd_show"
|
||||
class="downloadShowMenuItem"
|
||||
#ifdef XP_MACOSX
|
||||
|
|
|
@ -29,6 +29,26 @@ const TestCases = [
|
|||
tabSelected: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Download panel, system viewer menu items prefd off",
|
||||
whichUI: "downloadPanel",
|
||||
itemSelector: "#downloadsListBox richlistitem .downloadMainArea",
|
||||
async userEvents(itemTarget, win) {
|
||||
EventUtils.synthesizeMouseAtCenter(itemTarget, {}, win);
|
||||
},
|
||||
prefs: [
|
||||
["browser.download.openInSystemViewerContextMenuItem", false],
|
||||
["browser.download.alwaysOpenInSystemViewerContextMenuItem", false],
|
||||
],
|
||||
expected: {
|
||||
downloadCount: 1,
|
||||
newWindow: false,
|
||||
opensTab: true,
|
||||
tabSelected: true,
|
||||
useSystemMenuItemDisabled: true,
|
||||
alwaysMenuItemDisabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Download panel, open from keyboard",
|
||||
whichUI: "downloadPanel",
|
||||
|
@ -109,6 +129,26 @@ const TestCases = [
|
|||
tabSelected: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Library all downloads dialog, system viewer menu items prefd off",
|
||||
whichUI: "allDownloads",
|
||||
async userEvents(itemTarget, win) {
|
||||
// double click
|
||||
await triggerDblclickOn(itemTarget, {}, win);
|
||||
},
|
||||
prefs: [
|
||||
["browser.download.openInSystemViewerContextMenuItem", false],
|
||||
["browser.download.alwaysOpenInSystemViewerContextMenuItem", false],
|
||||
],
|
||||
expected: {
|
||||
downloadCount: 1,
|
||||
newWindow: false,
|
||||
opensTab: true,
|
||||
tabSelected: true,
|
||||
useSystemMenuItemDisabled: true,
|
||||
alwaysMenuItemDisabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Library all downloads dialog, open from keyboard",
|
||||
whichUI: "allDownloads",
|
||||
|
@ -189,6 +229,28 @@ const TestCases = [
|
|||
tabSelected: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "about:downloads, system viewer menu items prefd off",
|
||||
whichUI: "aboutDownloads",
|
||||
itemSelector: "#downloadsRichListBox richlistitem .downloadContainer",
|
||||
async userEvents(itemSelector, win) {
|
||||
let browser = win.gBrowser.selectedBrowser;
|
||||
is(browser.currentURI.spec, "about:downloads");
|
||||
await contentTriggerDblclickOn(itemSelector, {}, browser);
|
||||
},
|
||||
prefs: [
|
||||
["browser.download.openInSystemViewerContextMenuItem", false],
|
||||
["browser.download.alwaysOpenInSystemViewerContextMenuItem", false],
|
||||
],
|
||||
expected: {
|
||||
downloadCount: 1,
|
||||
newWindow: false,
|
||||
opensTab: true,
|
||||
tabSelected: true,
|
||||
useSystemMenuItemDisabled: true,
|
||||
alwaysMenuItemDisabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "about:downloads, open in new window",
|
||||
whichUI: "aboutDownloads",
|
||||
|
@ -306,6 +368,66 @@ function contentTriggerDblclickOn(selector, eventModifiers = {}, browser) {
|
|||
);
|
||||
}
|
||||
|
||||
async function openContextMenu(itemElement, win = window) {
|
||||
let popupShownPromise = BrowserTestUtils.waitForEvent(
|
||||
itemElement.ownerDocument,
|
||||
"popupshown"
|
||||
);
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
itemElement,
|
||||
{
|
||||
type: "contextmenu",
|
||||
button: 2,
|
||||
},
|
||||
win
|
||||
);
|
||||
let { target } = await popupShownPromise;
|
||||
return target;
|
||||
}
|
||||
|
||||
async function verifyContextMenu(contextMenu, expected = {}) {
|
||||
info("verifyContextMenu with expected: " + JSON.stringify(expected, null, 2));
|
||||
let alwaysMenuItem = contextMenu.querySelector(
|
||||
".downloadAlwaysUseSystemDefaultMenuItem"
|
||||
);
|
||||
let useSystemMenuItem = contextMenu.querySelector(
|
||||
".downloadUseSystemDefaultMenuItem"
|
||||
);
|
||||
await TestUtils.waitForCondition(
|
||||
() => BrowserTestUtils.is_visible(contextMenu),
|
||||
"The context menu is visible"
|
||||
);
|
||||
await TestUtils.waitForTick();
|
||||
|
||||
is(
|
||||
BrowserTestUtils.is_hidden(useSystemMenuItem),
|
||||
expected.useSystemMenuItemDisabled,
|
||||
`The 'Use system viewer' menu item was ${
|
||||
expected.useSystemMenuItemDisabled ? "hidden" : "visible"
|
||||
}`
|
||||
);
|
||||
is(
|
||||
BrowserTestUtils.is_hidden(alwaysMenuItem),
|
||||
expected.alwaysMenuItemDisabled,
|
||||
`The 'Use system viewer' menu item was ${
|
||||
expected.alwaysMenuItemDisabled ? "hidden" : "visible"
|
||||
}`
|
||||
);
|
||||
|
||||
if (!expected.useSystemMenuItemDisabled && expected.alwaysChecked) {
|
||||
is(
|
||||
alwaysMenuItem.getAttribute("checked"),
|
||||
"true",
|
||||
"The 'Always...' menu item is checked"
|
||||
);
|
||||
} else if (!expected.useSystemMenuItemDisabled) {
|
||||
ok(
|
||||
!alwaysMenuItem.hasAttribute("checked"),
|
||||
"The 'Always...' menu item not checked"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function createDownloadedFile(pathname, contents) {
|
||||
let encoder = new TextEncoder();
|
||||
let file = new FileUtils.File(pathname);
|
||||
|
@ -352,7 +474,7 @@ async function addPDFDownload(itemData) {
|
|||
return download;
|
||||
}
|
||||
|
||||
async function testSetup(testData = {}) {
|
||||
async function testSetup() {
|
||||
// remove download files, empty out collections
|
||||
let downloadList = await Downloads.getList(Downloads.ALL);
|
||||
let downloadCount = (await downloadList.getAll()).length;
|
||||
|
@ -379,6 +501,7 @@ async function testOpenPDFPreview({
|
|||
whichUI,
|
||||
itemSelector,
|
||||
expected,
|
||||
prefs = [],
|
||||
userEvents,
|
||||
isPrivate,
|
||||
}) {
|
||||
|
@ -386,6 +509,11 @@ async function testOpenPDFPreview({
|
|||
// Wait for focus first
|
||||
await promiseFocus();
|
||||
await testSetup();
|
||||
if (prefs.length) {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: prefs,
|
||||
});
|
||||
}
|
||||
|
||||
// Populate downloads database with the data required by this test.
|
||||
info("Adding download objects");
|
||||
|
@ -454,12 +582,16 @@ async function testOpenPDFPreview({
|
|||
}
|
||||
|
||||
let itemTarget;
|
||||
let contextMenu;
|
||||
|
||||
switch (whichUI) {
|
||||
case "downloadPanel":
|
||||
info("Opening download panel");
|
||||
await openDownloadPanel(expected.downloadCount);
|
||||
info("/Opening download panel");
|
||||
itemTarget = document.querySelector(itemSelector);
|
||||
contextMenu = uiWindow.document.querySelector("#downloadsContextMenu");
|
||||
|
||||
break;
|
||||
case "allDownloads":
|
||||
// we'll be interacting with the library dialog
|
||||
|
@ -467,11 +599,17 @@ async function testOpenPDFPreview({
|
|||
|
||||
let listbox = uiWindow.document.getElementById("downloadsRichListBox");
|
||||
ok(listbox, "download list box present");
|
||||
// wait for the expected number of items in the view
|
||||
await TestUtils.waitForCondition(
|
||||
() => listbox.itemChildren.length == expected.downloadCount
|
||||
);
|
||||
// wait for the expected number of items in the view,
|
||||
// and for the first item to be visible && clickable
|
||||
await TestUtils.waitForCondition(() => {
|
||||
return (
|
||||
listbox.itemChildren.length == expected.downloadCount &&
|
||||
BrowserTestUtils.is_visible(listbox.itemChildren[0])
|
||||
);
|
||||
});
|
||||
itemTarget = listbox.itemChildren[0];
|
||||
contextMenu = uiWindow.document.querySelector("#downloadsContextMenu");
|
||||
|
||||
break;
|
||||
case "aboutDownloads":
|
||||
info("Preparing about:downloads browser window");
|
||||
|
@ -537,6 +675,21 @@ async function testOpenPDFPreview({
|
|||
break;
|
||||
}
|
||||
|
||||
if (contextMenu) {
|
||||
info("trigger the contextmenu");
|
||||
await openContextMenu(itemTarget || itemSelector, uiWindow);
|
||||
info("context menu should be open, verify its menu items");
|
||||
let expectedValues = {
|
||||
useSystemMenuItemDisabled: false,
|
||||
alwaysMenuItemDisabled: false,
|
||||
...expected,
|
||||
};
|
||||
await verifyContextMenu(contextMenu, expectedValues);
|
||||
contextMenu.hidePopup();
|
||||
} else {
|
||||
todo(contextMenu, "No context menu checks for test: " + name);
|
||||
}
|
||||
|
||||
info("Executing user events");
|
||||
await userEvents(itemTarget || itemSelector, uiWindow);
|
||||
|
||||
|
@ -594,6 +747,9 @@ async function testOpenPDFPreview({
|
|||
await lastPBContextExitedPromise;
|
||||
});
|
||||
await downloadList.removeFinished();
|
||||
if (prefs.length) {
|
||||
await SpecialPowers.popPrefEnv();
|
||||
}
|
||||
}
|
||||
|
||||
// register the tests
|
||||
|
|
|
@ -726,6 +726,9 @@ Download.prototype = {
|
|||
* @param options.openWhere Optional string indicating how to open when handling
|
||||
* download by opening the target file URI.
|
||||
* One of "window", "tab", "tabshifted"
|
||||
* @param options.useSystemDefault
|
||||
* Optional value indicating how to handle launching this download,
|
||||
* this time only. Will override the associated mimeInfo.preferredAction
|
||||
* @return {Promise}
|
||||
* @resolves When the instruction to launch the file has been
|
||||
* successfully given to the operating system. Note that
|
||||
|
|
|
@ -712,6 +712,9 @@ var DownloadIntegration = {
|
|||
* @param options.openWhere Optional string indicating how to open when handling
|
||||
* download by opening the target file URI.
|
||||
* One of "window", "tab", "tabshifted"
|
||||
* @param options.useSystemDefault
|
||||
* Optional value indicating how to handle launching this download,
|
||||
* this time only. Will override the associated mimeInfo.preferredAction
|
||||
*
|
||||
* @return {Promise}
|
||||
* @resolves When the instruction to launch the file has been
|
||||
|
@ -721,7 +724,7 @@ var DownloadIntegration = {
|
|||
* @rejects JavaScript exception if there was an error trying to launch
|
||||
* the file.
|
||||
*/
|
||||
async launchDownload(aDownload, { openWhere }) {
|
||||
async launchDownload(aDownload, { openWhere, useSystemDefault = null }) {
|
||||
let file = new FileUtils.File(aDownload.target.path);
|
||||
|
||||
// In case of a double extension, like ".tar.gz", we only
|
||||
|
@ -794,7 +797,8 @@ var DownloadIntegration = {
|
|||
const PDF_CONTENT_TYPE = "application/pdf";
|
||||
if (
|
||||
aDownload.handleInternally ||
|
||||
(mimeInfo &&
|
||||
(!useSystemDefault && // No explicit instruction was passed to launch this download using the default system viewer.
|
||||
mimeInfo &&
|
||||
(mimeInfo.type == PDF_CONTENT_TYPE ||
|
||||
fileExtension?.toLowerCase() == "pdf") &&
|
||||
!mimeInfo.alwaysAskBeforeHandling &&
|
||||
|
|
Загрузка…
Ссылка в новой задаче