diff --git a/common/content/commandline.js b/common/content/commandline.js index 0b103997..075e3810 100644 --- a/common/content/commandline.js +++ b/common/content/commandline.js @@ -893,20 +893,21 @@ var CommandLine = Module("commandline", { */ input: function _input(prompt, callback, extra) { extra = extra || {}; + let closure = extra.closure || extra; this._input = { - submit: callback || extra.onAccept, - change: extra.onChange, - complete: extra.completer, - cancel: extra.onCancel + submit: callback || closure.onAccept, + change: closure.onChange, + complete: closure.completer, + cancel: closure.onCancel }; modes.push(modes.COMMAND_LINE, modes.PROMPT | extra.extended, update(Object.create(extra), { - onEvent: extra.onEvent || this.closure.onEvent, + onEvent: closure.onEvent || this.closure.onEvent, leave: function leave(stack) { commandline.leave(stack); - leave.supercall(this, stack); + leave.supercall(extra, stack); }, keyModes: [extra.extended, modes.PROMPT] })); diff --git a/common/modules/config.jsm b/common/modules/config.jsm index 42434f5f..994d39c0 100644 --- a/common/modules/config.jsm +++ b/common/modules/config.jsm @@ -500,25 +500,27 @@ var ConfigBase = Class("ConfigBase", { Button::after content: "]"; color: gray; text-decoration: none !important; Button:not([collapsed]) ~ Button:not([collapsed])::before content: "/["; + DownloadCell display: table-cell; padding: 0 1ex; + Downloads display: table; margin: 0; padding: 0; DownloadHead;;;CompTitle display: table-row; - DownloadHead>*;;;DownloadCell display: table-cell; + DownloadHead>*;;;DownloadCell Download display: table-row; Download:not([active]) color: gray; Buttons - DownloadCell display: table-cell; padding: 0 1ex; - DownloadButtons;;;DownloadCell - DownloadPercent;;;DownloadCell - DownloadProgress;;;DownloadCell + Download>*;;;DownloadCell + DownloadButtons + DownloadPercent + DownloadProgress DownloadProgressHave DownloadProgressTotal - DownloadSource;;;DownloadCell,URL - DownloadState;;;DownloadCell - DownloadTime;;;DownloadCell - DownloadTitle;;;DownloadCell,URL + DownloadSource + DownloadState + DownloadTime + DownloadTitle DownloadTitle>Link>a max-width: 48ex; overflow: hidden; display: inline-block; AddonCell display: table-cell; padding: 0 1ex; diff --git a/common/modules/downloads.jsm b/common/modules/downloads.jsm index de11b6b3..1eb3acd1 100644 --- a/common/modules/downloads.jsm +++ b/common/modules/downloads.jsm @@ -66,7 +66,7 @@ var Download = Class("Download", { get alive() this.inState(["downloading", "notstarted", "paused", "queued", "scanning"]), - allowed: Class.memoize(function () let (self = this) ({ + allowedCommands: Class.memoize(function () let (self = this) ({ get cancel() self.cancelable && self.inState(["downloading", "paused", "starting"]), get delete() !this.cancel && self.targetFile.exists(), get launch() self.targetFile.exists() && self.inState(["finished"]), @@ -78,13 +78,10 @@ var Download = Class("Download", { })), command: function command(name) { - util.assert(set.has(this.allowed, name), "Unknown command"); - util.assert(this.allowed[name], "Command not allowed"); + util.assert(set.has(this.allowedCommands, name), "Unknown command"); + util.assert(this.allowedCommands[name], "Command not allowed"); - if (set.has(this.commands, name)) - this.commands[name].call(this); - else - services.downloadManager[name + "Download"](this.id); + services.downloadManager[name + "Download"](this.id); }, commands: { @@ -154,8 +151,11 @@ var Download = Class("Download", { this.nodes.row.setAttribute("status", this.status); this.nodes.state.textContent = util.capitalize(this.status); - for (let [command, enabled] in Iterator(this.allowed)) - this.nodes[command].collapsed = !enabled; + + for (let node in values(this.nodes)) + if (node.update) + node.update(); + this.updateProgress(); } }); @@ -166,7 +166,9 @@ var DownloadList = Class("DownloadList", Ci.nsISupportsWeakReference]), { init: function init(modules, filter) { this.modules = modules; - this.nodes = {}; + this.nodes = { + commandTarget: this + }; this.filter = filter && filter.toLowerCase(); this.downloads = {}; }, @@ -181,17 +183,30 @@ var DownloadList = Class("DownloadList",
  • Title Status - + Progress - + Time remaining Source
  • +
  • +
  • + Totals: + + + Clear + + + + + +
  • , this.document, this.nodes); for (let row in iter(services.downloadManager.DBConnection .createStatement("SELECT id FROM moz_downloads"))) this.addDownload(row.id); + this.update(); util.addObserver(this); services.downloadManager.addListener(this); @@ -224,14 +239,31 @@ var DownloadList = Class("DownloadList", this.cleanup(); }, + allowedCommands: Class.memoize(function () let (self = this) ({ + get clear() values(self.downloads).some(function (dl) dl.allowedCommands.remove) + })), + + commands: { + clear: function () { + services.downloadManager.cleanUp(); + } + }, + + update: function update() { + for (let node in values(this.nodes)) + if (node.update && node.update != update) + node.update(); + }, + observers: { "download-manager-remove-download": function (id) { if (id == null) - id = [k for ([k, dl] in iter(this.downloads)) if (dl.allowed.remove)]; + id = [k for ([k, dl] in iter(this.downloads)) if (dl.allowedCommands.remove)]; else id = [id.QueryInterface(Ci.nsISupportsPRUint32).data]; Array.concat(id).map(this.closure.removeDownload); + this.update(); } }, @@ -245,6 +277,7 @@ var DownloadList = Class("DownloadList", this.modules.commandline.updateOutputHeight(false); this.nodes.list.scrollIntoView(false); } + this.update(); } catch (e) { util.reportError(e); diff --git a/common/modules/template.jsm b/common/modules/template.jsm index 178d0259..d9db8cb6 100644 --- a/common/modules/template.jsm +++ b/common/modules/template.jsm @@ -104,15 +104,32 @@ var Template = Module("Template", { init.supercall(this, node); this.target = params.commandTarget; - if (callable(this.target)) - this.target = { command: this.target } }, + get command() this.getAttribute("command") || this.getAttribute("key"), + events: { "click": function onClick(event) { event.preventDefault(); - this.target.command(this.getAttribute("key")); + if (this.commandAllowed) { + if (set.has(this.target.commands || {}, this.command)) + this.target.commands[this.command].call(this.target); + else + this.target.command(this.command); + } } + }, + + get commandAllowed() { + if (set.has(this.target.allowedCommands || {}, this.command)) + return this.target.allowedCommands[this.command]; + if ("commandAllowed" in this.target) + return this.target.commandAllowed(this.command); + return true; + }, + + update: function update() { + this.collapsed = !this.commandAllowed; } }) },