зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1269962 - Implement a popup menu for showing a submenu in Downloads Panel Footer., r=Paolo
MozReview-Commit-ID: 7K1W15039W8 --HG-- extra : rebase_source : 01b66909876cb22ea8442d037ebd8b8f3f5748ec
This commit is contained in:
Родитель
ff7bc87130
Коммит
9b70990ee3
|
@ -508,20 +508,32 @@ this.DownloadsCommon = {
|
|||
// or the file doesn't exist), try using the parent if we have it.
|
||||
let parent = aFile.parent;
|
||||
if (parent) {
|
||||
try {
|
||||
// Open the parent directory to show where the file should be.
|
||||
parent.launch();
|
||||
} catch (ex) {
|
||||
// If launch also fails (probably because it's not implemented), let
|
||||
// the OS handler try to open the parent.
|
||||
Cc["@mozilla.org/uriloader/external-protocol-service;1"]
|
||||
.getService(Ci.nsIExternalProtocolService)
|
||||
.loadUrl(NetUtil.newURI(parent));
|
||||
}
|
||||
this.showDirectory(parent);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Show the specified folder in the system file manager.
|
||||
*
|
||||
* @param aDirectory
|
||||
* a directory to be opened with system file manager.
|
||||
*/
|
||||
showDirectory(aDirectory) {
|
||||
if (!(aDirectory instanceof Ci.nsIFile)) {
|
||||
throw new Error("aDirectory must be a nsIFile object");
|
||||
}
|
||||
try {
|
||||
aDirectory.launch();
|
||||
} catch (ex) {
|
||||
// If launch fails (probably because it's not implemented), let
|
||||
// the OS handler try to open the directory.
|
||||
Cc["@mozilla.org/uriloader/external-protocol-service;1"]
|
||||
.getService(Ci.nsIExternalProtocolService)
|
||||
.loadUrl(NetUtil.newURI(aDirectory));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays an alert message box which asks the user if they want to
|
||||
* unblock the downloaded file or not.
|
||||
|
|
|
@ -19,7 +19,7 @@ richlistitem[type="download"].download-state[state="1"]:not([exists]) .downloadS
|
|||
|
||||
#downloadsSummary:not([inprogress]) > vbox > #downloadsSummaryProgress,
|
||||
#downloadsSummary:not([inprogress]) > vbox > #downloadsSummaryDetails,
|
||||
#downloadsFooter[showingsummary] > #downloadsHistory,
|
||||
#downloadsFooter[showingsummary] > #downloadsFooterButtons,
|
||||
#downloadsFooter:not([showingsummary]) > #downloadsSummary {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -367,6 +367,23 @@ const DownloadsPanel = {
|
|||
this._state = this.kStateHidden;
|
||||
},
|
||||
|
||||
onFooterPopupShowing(aEvent) {
|
||||
let itemClearList = document.getElementById("downloadsDropdownItemClearList");
|
||||
if (DownloadsCommon.getData(window).canRemoveFinished) {
|
||||
itemClearList.removeAttribute("hidden");
|
||||
} else {
|
||||
itemClearList.setAttribute("hidden", "true");
|
||||
}
|
||||
|
||||
document.getElementById("downloadsFooterButtonsSplitter").classList
|
||||
.add("downloadsDropmarkerSplitterExtend");
|
||||
},
|
||||
|
||||
onFooterPopupHidden(aEvent) {
|
||||
document.getElementById("downloadsFooterButtonsSplitter").classList
|
||||
.remove("downloadsDropmarkerSplitterExtend");
|
||||
},
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// Related operations
|
||||
|
||||
|
@ -382,6 +399,13 @@ const DownloadsPanel = {
|
|||
BrowserDownloadsUI();
|
||||
},
|
||||
|
||||
openDownloadsFolder() {
|
||||
Downloads.getPreferredDownloadsDirectory().then(downloadsPath => {
|
||||
DownloadsCommon.showDirectory(new FileUtils.File(downloadsPath));
|
||||
}).catch(Cu.reportError);
|
||||
this.hidePanel();
|
||||
},
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// Internal functions
|
||||
|
||||
|
@ -1188,6 +1212,9 @@ const DownloadsViewController = {
|
|||
//// nsIController
|
||||
|
||||
supportsCommand(aCommand) {
|
||||
if (aCommand === "downloadsCmd_clearList") {
|
||||
return true;
|
||||
}
|
||||
// Firstly, determine if this is a command that we can handle.
|
||||
if (!DownloadsViewUI.isCommandName(aCommand)) {
|
||||
return false;
|
||||
|
|
|
@ -104,8 +104,8 @@
|
|||
<menuseparator/>
|
||||
|
||||
<menuitem command="downloadsCmd_clearList"
|
||||
label="&cmd.clearList.label;"
|
||||
accesskey="&cmd.clearList.accesskey;"/>
|
||||
label="&cmd.clearList2.label;"
|
||||
accesskey="&cmd.clearList2.accesskey;"/>
|
||||
</menupopup>
|
||||
|
||||
<panelmultiview id="downloadsPanel-multiView"
|
||||
|
@ -148,11 +148,31 @@
|
|||
crop="end"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
<button id="downloadsHistory"
|
||||
class="plain downloadsPanelFooterButton"
|
||||
label="&downloadsHistory.label;"
|
||||
accesskey="&downloadsHistory.accesskey;"
|
||||
oncommand="DownloadsPanel.showDownloadsHistory();"/>
|
||||
<hbox id="downloadsFooterButtons">
|
||||
<button id="downloadsHistory"
|
||||
class="plain downloadsPanelFooterButton"
|
||||
label="&downloadsHistory.label;"
|
||||
accesskey="&downloadsHistory.accesskey;"
|
||||
flex="1"
|
||||
oncommand="DownloadsPanel.showDownloadsHistory();"/>
|
||||
<toolbarseparator id="downloadsFooterButtonsSplitter"
|
||||
class="downloadsDropmarkerSplitter"/>
|
||||
<button id="downloadsFooterDropmarker"
|
||||
class="plain downloadsPanelFooterButton downloadsDropmarker"
|
||||
type="menu">
|
||||
<menupopup id="downloadSubPanel"
|
||||
onpopupshowing="DownloadsPanel.onFooterPopupShowing(event);"
|
||||
onpopuphidden="DownloadsPanel.onFooterPopupHidden(event);"
|
||||
position="after_end">
|
||||
<menuitem id="downloadsDropdownItemClearList"
|
||||
command="downloadsCmd_clearList"
|
||||
label="&cmd.clearList2.label;"/>
|
||||
<menuitem id="downloadsDropdownItemOpenDownloadsFolder"
|
||||
oncommand="DownloadsPanel.openDownloadsFolder();"
|
||||
label="&openDownloadsFolder.label;"/>
|
||||
</menupopup>
|
||||
</button>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</panelview>
|
||||
|
||||
|
|
|
@ -10,3 +10,4 @@ skip-if = os == "linux" # Bug 952422
|
|||
[browser_confirm_unblock_download.js]
|
||||
[browser_iframe_gone_mid_download.js]
|
||||
[browser_downloads_panel_block.js]
|
||||
[browser_downloads_panel_footer.js]
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
"use strict";
|
||||
|
||||
function *task_openDownloadsSubPanel() {
|
||||
let downloadSubPanel = document.getElementById("downloadSubPanel");
|
||||
let popupShownPromise = BrowserTestUtils.waitForEvent(downloadSubPanel, "popupshown");
|
||||
|
||||
let downloadsDropmarker = document.getElementById("downloadsFooterDropmarker");
|
||||
EventUtils.synthesizeMouseAtCenter(downloadsDropmarker, {}, window);
|
||||
|
||||
yield popupShownPromise;
|
||||
}
|
||||
|
||||
add_task(function* test_openDownloadsFolder() {
|
||||
yield task_openPanel();
|
||||
|
||||
yield task_openDownloadsSubPanel();
|
||||
|
||||
yield new Promise(resolve => {
|
||||
sinon.stub(DownloadsCommon, "showDirectory", file => {
|
||||
resolve(Downloads.getPreferredDownloadsDirectory().then(downloadsPath => {
|
||||
is(file.path, downloadsPath, "Check the download folder path.");
|
||||
}));
|
||||
});
|
||||
|
||||
let itemOpenDownloadsFolder =
|
||||
document.getElementById("downloadsDropdownItemOpenDownloadsFolder");
|
||||
EventUtils.synthesizeMouseAtCenter(itemOpenDownloadsFolder, {}, window);
|
||||
});
|
||||
|
||||
yield task_resetState();
|
||||
});
|
||||
|
||||
add_task(function* test_clearList() {
|
||||
const kTestCases = [{
|
||||
downloads: [
|
||||
{ state: nsIDM.DOWNLOAD_NOTSTARTED },
|
||||
{ state: nsIDM.DOWNLOAD_FINISHED },
|
||||
{ state: nsIDM.DOWNLOAD_FAILED },
|
||||
{ state: nsIDM.DOWNLOAD_CANCELED },
|
||||
],
|
||||
expectClearListShown: true,
|
||||
expectedItemNumber: 0,
|
||||
},{
|
||||
downloads: [
|
||||
{ state: nsIDM.DOWNLOAD_NOTSTARTED },
|
||||
{ state: nsIDM.DOWNLOAD_FINISHED },
|
||||
{ state: nsIDM.DOWNLOAD_FAILED },
|
||||
{ state: nsIDM.DOWNLOAD_PAUSED },
|
||||
{ state: nsIDM.DOWNLOAD_CANCELED },
|
||||
],
|
||||
expectClearListShown: true,
|
||||
expectedItemNumber: 1,
|
||||
},{
|
||||
downloads: [
|
||||
{ state: nsIDM.DOWNLOAD_PAUSED },
|
||||
],
|
||||
expectClearListShown: false,
|
||||
expectedItemNumber: 1,
|
||||
}];
|
||||
|
||||
for (let testCase of kTestCases) {
|
||||
yield verify_clearList(testCase);
|
||||
}
|
||||
});
|
||||
|
||||
function *verify_clearList(testCase) {
|
||||
let downloads = testCase.downloads;
|
||||
yield task_addDownloads(downloads);
|
||||
|
||||
yield task_openPanel();
|
||||
is(DownloadsView._downloads.length, downloads.length,
|
||||
"Expect the number of download items");
|
||||
|
||||
yield task_openDownloadsSubPanel();
|
||||
|
||||
let itemClearList = document.getElementById("downloadsDropdownItemClearList");
|
||||
let itemNumberPromise = BrowserTestUtils.waitForCondition(() => {
|
||||
return DownloadsView._downloads.length === testCase.expectedItemNumber;
|
||||
});
|
||||
if (testCase.expectClearListShown) {
|
||||
isnot("true", itemClearList.getAttribute("hidden"),
|
||||
"Should show Clear Preview Panel button");
|
||||
EventUtils.synthesizeMouseAtCenter(itemClearList, {}, window);
|
||||
} else {
|
||||
is("true", itemClearList.getAttribute("hidden"),
|
||||
"Should not show Clear Preview Panel button");
|
||||
}
|
||||
|
||||
yield itemNumberPromise;
|
||||
is(DownloadsView._downloads.length, testCase.expectedItemNumber,
|
||||
"Download items remained.");
|
||||
|
||||
yield task_resetState();
|
||||
}
|
|
@ -24,8 +24,17 @@ const nsIDM = Ci.nsIDownloadManager;
|
|||
|
||||
var gTestTargetFile = FileUtils.getFile("TmpD", ["dm-ui-test.file"]);
|
||||
gTestTargetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
|
||||
|
||||
// Load mocking/stubbing library, sinon
|
||||
// docs: http://sinonjs.org/docs/
|
||||
Services.scriptloader.loadSubScript("resource://testing-common/sinon-1.16.1.js");
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gTestTargetFile.remove(false);
|
||||
|
||||
delete window.sinon;
|
||||
delete window.setImmediate;
|
||||
delete window.clearImmediate;
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -62,8 +62,8 @@
|
|||
<!ENTITY cmd.copyDownloadLink.accesskey "L">
|
||||
<!ENTITY cmd.removeFromHistory.label "Remove From History">
|
||||
<!ENTITY cmd.removeFromHistory.accesskey "e">
|
||||
<!ENTITY cmd.clearList.label "Clear List">
|
||||
<!ENTITY cmd.clearList.accesskey "a">
|
||||
<!ENTITY cmd.clearList2.label "Clear Preview Panel">
|
||||
<!ENTITY cmd.clearList2.accesskey "a">
|
||||
<!ENTITY cmd.clearDownloads.label "Clear Downloads">
|
||||
<!ENTITY cmd.clearDownloads.accesskey "D">
|
||||
<!-- LOCALIZATION NOTE (cmd.unblock2.label):
|
||||
|
@ -109,6 +109,8 @@
|
|||
<!ENTITY downloadsHistory.label "Show All Downloads">
|
||||
<!ENTITY downloadsHistory.accesskey "S">
|
||||
|
||||
<!ENTITY openDownloadsFolder.label "Open Downloads Folder">
|
||||
|
||||
<!ENTITY clearDownloadsButton.label "Clear Downloads">
|
||||
<!ENTITY clearDownloadsButton.tooltip "Clears completed, canceled and failed downloads">
|
||||
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
}
|
||||
|
||||
#emptyDownloads {
|
||||
padding: 10px 20px;
|
||||
padding: 16px 25px;
|
||||
margin: 0;
|
||||
/* The panel can be wider than this description after the blocked subview is
|
||||
shown, so center the text. */
|
||||
text-align: center;
|
||||
|
@ -41,7 +42,7 @@
|
|||
border-top: 1px solid var(--panel-separator-color);
|
||||
}
|
||||
|
||||
.downloadsPanelFooter > toolbarseparator {
|
||||
.downloadsPanelFooter toolbarseparator {
|
||||
margin: 0;
|
||||
border: 0;
|
||||
min-width: 0;
|
||||
|
@ -55,6 +56,7 @@
|
|||
color: inherit;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
min-width: 0;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
|
@ -63,7 +65,8 @@
|
|||
background-color: hsla(210,4%,10%,.07);
|
||||
}
|
||||
|
||||
.downloadsPanelFooterButton:hover:active {
|
||||
.downloadsPanelFooterButton:hover:active,
|
||||
.downloadsPanelFooterButton[open="true"] {
|
||||
outline: 1px solid hsla(210,4%,10%,.12);
|
||||
background-color: hsla(210,4%,10%,.12);
|
||||
box-shadow: 0 1px 0 hsla(210,4%,10%,.05) inset;
|
||||
|
@ -82,6 +85,47 @@
|
|||
background-color: #0568ba;
|
||||
}
|
||||
|
||||
#downloadsPanel[hasdownloads] #downloadsHistory {
|
||||
padding-left: 58px !important;
|
||||
}
|
||||
|
||||
toolbarseparator.downloadsDropmarkerSplitter {
|
||||
margin: 7px 0;
|
||||
}
|
||||
|
||||
#downloadsFooter:hover toolbarseparator.downloadsDropmarkerSplitter,
|
||||
#downloadsFooter toolbarseparator.downloadsDropmarkerSplitterExtend {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.downloadsDropmarker {
|
||||
padding: 0 19px !important;
|
||||
}
|
||||
|
||||
.downloadsDropmarker > .button-box > hbox {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.downloadsDropmarker > .button-box > .button-menu-dropmarker {
|
||||
/* This is to override the linux !important */
|
||||
-moz-appearance: none !important;
|
||||
display: -moz-box;
|
||||
}
|
||||
|
||||
.downloadsDropmarker > .button-box > .button-menu-dropmarker > .dropmarker-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
list-style-image: url("chrome://browser/skin/downloads/menubutton-dropmarker.svg");
|
||||
filter: url("chrome://browser/skin/filters.svg#fill");
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
/* Override default icon size which is too small for this dropdown */
|
||||
.downloadsDropmarker > .button-box > .button-menu-dropmarker {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
#downloadsSummary {
|
||||
--summary-padding-end: 38px;
|
||||
--summary-padding-start: 12px;
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="16" height="16" viewBox="0 0 16 16">
|
||||
<path d="m 2,6 6,6 6,-6 -1.5,-1.5 -4.5,4.5 -4.5,-4.5 z" />
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 391 B |
|
@ -54,6 +54,7 @@
|
|||
skin/classic/browser/customizableui/whimsy@2x.png (../shared/customizableui/whimsy@2x.png)
|
||||
skin/classic/browser/downloads/contentAreaDownloadsView.css (../shared/downloads/contentAreaDownloadsView.css)
|
||||
skin/classic/browser/downloads/download-blocked.svg (../shared/downloads/download-blocked.svg)
|
||||
skin/classic/browser/downloads/menubutton-dropmarker.svg (../shared/downloads/menubutton-dropmarker.svg)
|
||||
skin/classic/browser/drm-icon.svg (../shared/drm-icon.svg)
|
||||
skin/classic/browser/filters.svg (../shared/filters.svg)
|
||||
skin/classic/browser/fullscreen/insecure.svg (../shared/fullscreen/insecure.svg)
|
||||
|
|
Загрузка…
Ссылка в новой задаче