Bug 827608 - Use html context menus for about:downloads. r=bnicholson, r=minkle

This commit is contained in:
Wes Johnston 2013-01-09 11:28:36 -08:00
Родитель 36b3e30caf
Коммит aa8c0e0589
5 изменённых файлов: 113 добавлений и 76 удалений

Просмотреть файл

@ -12,7 +12,7 @@ Cu.import("resource://gre/modules/PluralForm.jsm");
let gStrings = Services.strings.createBundle("chrome://browser/locale/aboutDownloads.properties");
let downloadTemplate =
"<li downloadID='{id}' role='button' state='{state}'>" +
"<li downloadID='{id}' role='button' state='{state}' contextmenu='downloadmenu'>" +
"<img class='icon' src='{icon}'/>" +
"<div class='details'>" +
"<div class='row'>" +
@ -35,6 +35,86 @@ XPCOMUtils.defineLazyGetter(window, "gChromeWin", function ()
.getInterface(Ci.nsIDOMWindow)
.QueryInterface(Ci.nsIDOMChromeWindow));
var ContextMenus = {
target: null,
init: function() {
document.addEventListener("contextmenu", this, false);
this.items = [
{ name: "open", states: [Downloads._dlmgr.DOWNLOAD_FINISHED] },
{ name: "retry", states: [Downloads._dlmgr.DOWNLOAD_FAILED, Downloads._dlmgr.DOWNLOAD_CANCELED] },
{ name: "remove", states: [Downloads._dlmgr.DOWNLOAD_FINISHED,Downloads._dlmgr.DOWNLOAD_FAILED, Downloads._dlmgr.DOWNLOAD_CANCELED] },
{ name: "removeall", states: [Downloads._dlmgr.DOWNLOAD_FINISHED,Downloads._dlmgr.DOWNLOAD_FAILED, Downloads._dlmgr.DOWNLOAD_CANCELED] },
{ name: "pause", states: [Downloads._dlmgr.DOWNLOAD_DOWNLOADING] },
{ name: "resume", states: [Downloads._dlmgr.DOWNLOAD_PAUSED] },
{ name: "cancel", states: [Downloads._dlmgr.DOWNLOAD_DOWNLOADING, Downloads._dlmgr.DOWNLOAD_NOTSTARTED, Downloads._dlmgr.DOWNLOAD_QUEUED, Downloads._dlmgr.DOWNLOAD_PAUSED] },
];
},
handleEvent: function(event) {
// store the target of context menu events so that we know which app to act on
this.target = event.target;
while (!this.target.hasAttribute("contextmenu")) {
this.target = this.target.parentNode;
}
if (!this.target)
return;
let state = parseInt(this.target.getAttribute("state"));
for (let i = 0; i < this.items.length; i++) {
var item = this.items[i];
let enabled = (item.states.indexOf(state) > -1);
if (enabled)
document.getElementById("contextmenu-" + item.name).removeAttribute("hidden");
else
document.getElementById("contextmenu-" + item.name).setAttribute("hidden", "true");
}
},
// Open shown only for downloads that completed successfully
open: function(event) {
Downloads.openDownload(this.target);
this.target = null;
},
// Retry shown when its failed, canceled, blocked(covered in failed, see _getState())
retry: function (event) {
Downloads.retryDownload(this.target);
this.target = null;
},
// Remove shown when its canceled, finished, failed(failed includes blocked and dirty, see _getState())
remove: function (event) {
Downloads.removeDownload(this.target);
this.target = null;
},
// Pause shown when item is currently downloading
pause: function (event) {
Downloads.pauseDownload(this.target);
this.target = null;
},
// Resume shown for paused items only
resume: function (event) {
Downloads.resumeDownload(this.target);
this.target = null;
},
// Cancel shown when its downloading, notstarted, queued or paused
cancel: function (event) {
Downloads.cancelDownload(this.target);
this.target = null;
},
removeAll: function(event) {
Downloads.removeAll();
this.target = null;
}
}
let Downloads = {
init: function dl_init() {
this._list = document.getElementById("downloads-list");
@ -56,70 +136,7 @@ let Downloads = {
Services.obs.addObserver(this, "dl-cancel", false);
this.getDownloads();
let contextmenus = gChromeWin.NativeWindow.contextmenus;
// Open shown only for downloads that completed successfully
Downloads.openMenuItem = contextmenus.add(gStrings.GetStringFromName("downloadAction.open"),
contextmenus.SelectorContext("li[state='" + this._dlmgr.DOWNLOAD_FINISHED + "']"),
function (aTarget) {
Downloads.openDownload(aTarget);
}
);
// Retry shown when its failed, canceled, blocked(covered in failed, see _getState())
Downloads.retryMenuItem = contextmenus.add(gStrings.GetStringFromName("downloadAction.retry"),
contextmenus.SelectorContext("li[state='" + this._dlmgr.DOWNLOAD_FAILED + "']," +
"li[state='" + this._dlmgr.DOWNLOAD_CANCELED + "']"),
function (aTarget) {
Downloads.retryDownload(aTarget);
}
);
// Remove shown when its canceled, finished, failed(failed includes blocked and dirty, see _getState())
Downloads.removeMenuItem = contextmenus.add(gStrings.GetStringFromName("downloadAction.remove"),
contextmenus.SelectorContext("li[state='" + this._dlmgr.DOWNLOAD_CANCELED + "']," +
"li[state='" + this._dlmgr.DOWNLOAD_FINISHED + "']," +
"li[state='" + this._dlmgr.DOWNLOAD_FAILED + "']"),
function (aTarget) {
Downloads.removeDownload(aTarget);
}
);
// Pause shown when item is currently downloading
Downloads.pauseMenuItem = contextmenus.add(gStrings.GetStringFromName("downloadAction.pause"),
contextmenus.SelectorContext("li[state='" + this._dlmgr.DOWNLOAD_DOWNLOADING + "']"),
function (aTarget) {
Downloads.pauseDownload(aTarget);
}
);
// Resume shown for paused items only
Downloads.resumeMenuItem = contextmenus.add(gStrings.GetStringFromName("downloadAction.resume"),
contextmenus.SelectorContext("li[state='" + this._dlmgr.DOWNLOAD_PAUSED + "']"),
function (aTarget) {
Downloads.resumeDownload(aTarget);
}
);
// Cancel shown when its downloading, notstarted, queued or paused
Downloads.cancelMenuItem = contextmenus.add(gStrings.GetStringFromName("downloadAction.cancel"),
contextmenus.SelectorContext("li[state='" + this._dlmgr.DOWNLOAD_DOWNLOADING + "']," +
"li[state='" + this._dlmgr.DOWNLOAD_NOTSTARTED + "']," +
"li[state='" + this._dlmgr.DOWNLOAD_QUEUED + "']," +
"li[state='" + this._dlmgr.DOWNLOAD_PAUSED + "']"),
function (aTarget) {
Downloads.cancelDownload(aTarget);
}
);
// Delete All shown when item is finished, canceled, or failed
Downloads.deleteAllMenuItem = contextmenus.add(gStrings.GetStringFromName("downloadAction.deleteAll"),
contextmenus.SelectorContext("li[state='" + this._dlmgr.DOWNLOAD_FINISHED + "']," +
"li[state='" + this._dlmgr.DOWNLOAD_CANCELED + "']," +
"li[state='" + this._dlmgr.DOWNLOAD_FAILED + "']"),
this.deleteAll.bind(this)
);
ContextMenus.init();
},
uninit: function dl_uninit() {
@ -420,7 +437,7 @@ let Downloads = {
} catch(ex) { }
},
deleteAll: function dl_deleteAll() {
removeAll: function dl_removeAll() {
let title = gStrings.GetStringFromName("downloadAction.deleteAll");
let messageForm = gStrings.GetStringFromName("downloadMessage.deleteAll");
let elements = this._list.querySelectorAll("li[state='" + this._dlmgr.DOWNLOAD_FINISHED + "']," +

Просмотреть файл

@ -24,6 +24,16 @@
</head>
<body dir="&locale.dir;" onload="Downloads.init();" onunload="Downloads.uninit();">
<menu type="context" id="downloadmenu">
<menuitem id="contextmenu-open" label="&aboutDownloads.open;" onclick="ContextMenus.open();"></menuitem>
<menuitem id="contextmenu-retry" label="&aboutDownloads.retry;" onclick="ContextMenus.retry();"></menuitem>
<menuitem id="contextmenu-remove" label="&aboutDownloads.remove;" onclick="ContextMenus.remove();"></menuitem>
<menuitem id="contextmenu-pause" label="&aboutDownloads.pause;" onclick="ContextMenus.pause();"></menuitem>
<menuitem id="contextmenu-resume" label="&aboutDownloads.resume;" onclick="ContextMenus.resume();"></menuitem>
<menuitem id="contextmenu-cancel" label="&aboutDownloads.cancel;" onclick="ContextMenus.cancel();"></menuitem>
<menuitem id="contextmenu-removeall" label="&aboutDownloads.removeAll;" onclick="ContextMenus.removeAll();"></menuitem>
</menu>
<div class="header">
<div>&aboutDownloads.header;</div>
</div>

Просмотреть файл

@ -1556,7 +1556,7 @@ var NativeWindow = {
_addHTMLContextMenuItems: function cm_addContextMenuItems(aMenu, aParent) {
for (let i = 0; i < aMenu.childNodes.length; i++) {
let item = aMenu.childNodes[i];
if (!item.label || item.hasAttribute("hidden"))
if (!item.label)
continue;
let id = this._contextId++;
@ -1578,6 +1578,9 @@ var NativeWindow = {
}).bind(this),
getValue: function(aElt) {
if (item.hasAttribute("hidden"))
return null;
return {
icon: item.icon,
label: item.label,
@ -1703,9 +1706,16 @@ var NativeWindow = {
// convert this.menuitems object to an array for sending to native code
let itemArray = [];
for (let i = 0; i < this.menuitems.length; i++) {
itemArray.push(this.menuitems[i].getValue(aTarget));
let val = this.menuitems[i].getValue(aTarget);
// hidden menu items will return null from getValue
if (val)
itemArray.push(val);
}
if (itemArray.length == 0)
return;
let msg = {
gecko: {
type: "Prompt:Show",

Просмотреть файл

@ -5,3 +5,11 @@
<!ENTITY aboutDownloads.title "Downloads">
<!ENTITY aboutDownloads.header "Your Downloads">
<!ENTITY aboutDownloads.empty "No Downloads">
<!ENTITY aboutDownloads.open "Open">
<!ENTITY aboutDownloads.remove "Delete">
<!ENTITY aboutDownloads.removeAll "Delete All">
<!ENTITY aboutDownloads.pause "Pause">
<!ENTITY aboutDownloads.resume "Resume">
<!ENTITY aboutDownloads.cancel "Cancel">
<!ENTITY aboutDownloads.retry "Retry">

Просмотреть файл

@ -2,19 +2,11 @@
# 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/.
downloadAction.open=Open
downloadAction.remove=Delete
downloadAction.deleteAll=Delete All
# LOCALIZATION NOTE (downloadMessage.deleteAll):
# Semi-colon list of plural forms. See:
# http://developer.mozilla.org/en/docs/Localization_and_Plurals
downloadMessage.deleteAll=Delete this download?;Delete #1 downloads?
downloadAction.pause=Pause
downloadAction.resume=Resume
downloadAction.cancel=Cancel
downloadAction.retry=Retry
downloadState.downloading=Downloading…
downloadState.canceled=Canceled
downloadState.failed=Failed