mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-20 18:17:58 +01:00
Update downloads.jsm to use Downloads.jsm rather than defunct downloads service.
This commit is contained in:
@@ -2136,7 +2136,8 @@ var ItemList = Class("ItemList", {
|
|||||||
|
|
||||||
// We need to collect all of the rescrolling functions in
|
// We need to collect all of the rescrolling functions in
|
||||||
// one go, as the height calculation that they need to do
|
// one go, as the height calculation that they need to do
|
||||||
// would force a reflow after each DOM modification.
|
// would force an expensive reflow after each call due to
|
||||||
|
// DOM modifications, otherwise.
|
||||||
this.activeGroups.filter(g => !g.collapsed)
|
this.activeGroups.filter(g => !g.collapsed)
|
||||||
.map(g => g.rescrollFunc)
|
.map(g => g.rescrollFunc)
|
||||||
.forEach(call);
|
.forEach(call);
|
||||||
@@ -2270,7 +2271,7 @@ var ItemList = Class("ItemList", {
|
|||||||
getGroup: function getGroup(context)
|
getGroup: function getGroup(context)
|
||||||
context instanceof ItemList.Group ? context
|
context instanceof ItemList.Group ? context
|
||||||
: context && context.getCache("itemlist-group",
|
: context && context.getCache("itemlist-group",
|
||||||
bind("Group", ItemList, this, context)),
|
() => ItemList.Group(this, context)),
|
||||||
|
|
||||||
getOffset: function getOffset(tuple) tuple && this.getGroup(tuple[0]).getOffset(tuple[1])
|
getOffset: function getOffset(tuple) tuple && this.getGroup(tuple[0]).getOffset(tuple[1])
|
||||||
}, {
|
}, {
|
||||||
|
|||||||
@@ -332,7 +332,7 @@ var HintSession = Class("HintSession", CommandMode, {
|
|||||||
__proto__: this.Hint
|
__proto__: this.Hint
|
||||||
});
|
});
|
||||||
|
|
||||||
for (let hint in values(_hints)) {
|
for (let hint of _hints) {
|
||||||
let { elem, rect } = hint;
|
let { elem, rect } = hint;
|
||||||
|
|
||||||
if (elem.hasAttributeNS(NS, "hint"))
|
if (elem.hasAttributeNS(NS, "hint"))
|
||||||
|
|||||||
@@ -162,13 +162,11 @@ download.nActive-1 = %S active
|
|||||||
download.almostDone = ~1 second
|
download.almostDone = ~1 second
|
||||||
download.unknown = Unknown
|
download.unknown = Unknown
|
||||||
|
|
||||||
download.action.Cancel = Cancel
|
|
||||||
download.action.Clear = Clear
|
download.action.Clear = Clear
|
||||||
download.action.Delete = Delete
|
download.action.Delete = Delete
|
||||||
download.action.Pause = Pause
|
download.action.Stop = Stop
|
||||||
download.action.Remove = Remove
|
download.action.Remove = Remove
|
||||||
download.action.Resume = Resume
|
download.action.Resume = Resume
|
||||||
download.action.Retry = Retry
|
|
||||||
|
|
||||||
editor.prompt.editPassword = Editing a password field externally will reveal the password. Would you like to continue? (yes/[no]):
|
editor.prompt.editPassword = Editing a password field externally will reveal the password. Would you like to continue? (yes/[no]):
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2009-2013 Kris Maglione <maglione.k@gmail.com>
|
// Copyright (c) 2009-2014 Kris Maglione <maglione.k@gmail.com>
|
||||||
//
|
//
|
||||||
// This work is licensed for reuse under an MIT license. Details are
|
// This work is licensed for reuse under an MIT license. Details are
|
||||||
// given in the LICENSE.txt file included with this file.
|
// given in the LICENSE.txt file included with this file.
|
||||||
@@ -6,10 +6,15 @@
|
|||||||
|
|
||||||
var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
|
var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
|
function module(url) {
|
||||||
|
let obj = {};
|
||||||
|
Cu.import(url, obj);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
var { XPCOMUtils } = module("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
try {
|
try {
|
||||||
var ctypes;
|
var ctypes = module("resource://gre/modules/ctypes.jsm");
|
||||||
Cu.import("resource://gre/modules/ctypes.jsm");
|
|
||||||
}
|
}
|
||||||
catch (e) {}
|
catch (e) {}
|
||||||
|
|
||||||
@@ -22,7 +27,11 @@ if (typeof XPCSafeJSObjectWrapper === "undefined")
|
|||||||
|
|
||||||
let getGlobalForObject = Cu.getGlobalForObject || (obj => obj.__parent__);
|
let getGlobalForObject = Cu.getGlobalForObject || (obj => obj.__parent__);
|
||||||
|
|
||||||
function require(module, target) JSMLoader.load(module, target);
|
function require(module_, target) {
|
||||||
|
if (/^[A-Za-z0-9]+:/.test(module_))
|
||||||
|
return module(module_);
|
||||||
|
return JSMLoader.load(module_, target);
|
||||||
|
}
|
||||||
|
|
||||||
function lazyRequire(module, names, target) {
|
function lazyRequire(module, names, target) {
|
||||||
for each (let name in names)
|
for each (let name in names)
|
||||||
@@ -133,13 +142,16 @@ function require_(obj, name, from, targetName) {
|
|||||||
defineModule("base", {
|
defineModule("base", {
|
||||||
// sed -n 's/^(const|var|function) ([a-zA-Z0-9_]+).*/ "\2",/p' base.jsm | sort | fmt
|
// sed -n 's/^(const|var|function) ([a-zA-Z0-9_]+).*/ "\2",/p' base.jsm | sort | fmt
|
||||||
exports: [
|
exports: [
|
||||||
"ErrorBase", "Cc", "Ci", "Class", "Cr", "Cu", "Finished", "Module", "JSMLoader",
|
"ErrorBase", "Cc", "Ci", "Class", "Cr", "Cu", "Finished",
|
||||||
"Set", "Struct", "StructBase", "Timer", "UTF8", "XPCOM", "XPCOMShim", "XPCOMUtils",
|
"Module", "JSMLoader", "RealSet", "Set", "Struct", "StructBase",
|
||||||
"XPCSafeJSObjectWrapper", "array", "bind", "call", "callable", "ctypes", "curry",
|
"Timer", "UTF8", "XPCOM", "XPCOMShim", "XPCOMUtils",
|
||||||
"debuggerProperties", "defineModule", "deprecated", "endModule", "forEach", "isArray",
|
"XPCSafeJSObjectWrapper", "array", "bind", "call", "callable",
|
||||||
"isGenerator", "isinstance", "isObject", "isString", "isSubclass", "isXML", "iter",
|
"ctypes", "curry", "debuggerProperties", "defineModule",
|
||||||
"iterAll", "iterOwnProperties", "keys", "literal", "memoize", "octal", "properties",
|
"deprecated", "endModule", "forEach", "isArray", "isGenerator",
|
||||||
"require", "set", "update", "values", "update_"
|
"isinstance", "isObject", "isString", "isSubclass", "isXML",
|
||||||
|
"iter", "iterAll", "iterOwnProperties", "keys", "literal",
|
||||||
|
"memoize", "modujle", "octal", "properties", "require", "set",
|
||||||
|
"update", "values", "update_"
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -318,9 +330,13 @@ deprecated.warn = function warn(func, name, alternative, frame) {
|
|||||||
* @returns {Generator}
|
* @returns {Generator}
|
||||||
*/
|
*/
|
||||||
function keys(obj) iter(function keys() {
|
function keys(obj) iter(function keys() {
|
||||||
for (var k in obj)
|
if (isinstance(obj, ["Map"]))
|
||||||
if (hasOwnProperty.call(obj, k))
|
for (let [k, v] of obj)
|
||||||
yield k;
|
yield k;
|
||||||
|
else
|
||||||
|
for (var k in obj)
|
||||||
|
if (hasOwnProperty.call(obj, k))
|
||||||
|
yield k;
|
||||||
}());
|
}());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -331,7 +347,10 @@ function keys(obj) iter(function keys() {
|
|||||||
* @returns {Generator}
|
* @returns {Generator}
|
||||||
*/
|
*/
|
||||||
function values(obj) iter(function values() {
|
function values(obj) iter(function values() {
|
||||||
if (isinstance(obj, ["Generator", "Iterator", Iter]))
|
if (isinstance(obj, ["Map"]))
|
||||||
|
for (let [k, v] of obj)
|
||||||
|
yield v;
|
||||||
|
else if (isinstance(obj, ["Generator", "Iterator", Iter]))
|
||||||
for (let k in obj)
|
for (let k in obj)
|
||||||
yield k;
|
yield k;
|
||||||
else
|
else
|
||||||
@@ -343,6 +362,8 @@ function values(obj) iter(function values() {
|
|||||||
var forEach = deprecated("iter.forEach", function forEach() iter.forEach.apply(iter, arguments));
|
var forEach = deprecated("iter.forEach", function forEach() iter.forEach.apply(iter, arguments));
|
||||||
var iterAll = deprecated("iter", function iterAll() iter.apply(null, arguments));
|
var iterAll = deprecated("iter", function iterAll() iter.apply(null, arguments));
|
||||||
|
|
||||||
|
var RealSet = Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility for managing sets of strings. Given an array, returns an
|
* Utility for managing sets of strings. Given an array, returns an
|
||||||
* object with one key for each value thereof.
|
* object with one key for each value thereof.
|
||||||
@@ -350,7 +371,7 @@ var iterAll = deprecated("iter", function iterAll() iter.apply(null, arguments))
|
|||||||
* @param {[string]} ary @optional
|
* @param {[string]} ary @optional
|
||||||
* @returns {object}
|
* @returns {object}
|
||||||
*/
|
*/
|
||||||
function Set(ary) {
|
this.Set = function Set(ary) {
|
||||||
let obj = {};
|
let obj = {};
|
||||||
if (ary)
|
if (ary)
|
||||||
for (let val in values(ary))
|
for (let val in values(ary))
|
||||||
@@ -1377,6 +1398,10 @@ function iter(obj, iface) {
|
|||||||
if (arguments.length == 2 && iface instanceof Ci.nsIJSIID)
|
if (arguments.length == 2 && iface instanceof Ci.nsIJSIID)
|
||||||
return iter(obj).map(item => item.QueryInterface(iface));
|
return iter(obj).map(item => item.QueryInterface(iface));
|
||||||
|
|
||||||
|
if (isinstance(obj, ["Map Iterator"]))
|
||||||
|
// This is stupid.
|
||||||
|
obj = { __iterator__: (function () this).bind(obj) };
|
||||||
|
|
||||||
let args = arguments;
|
let args = arguments;
|
||||||
let res = Iterator(obj);
|
let res = Iterator(obj);
|
||||||
|
|
||||||
@@ -1388,6 +1413,9 @@ function iter(obj, iface) {
|
|||||||
})();
|
})();
|
||||||
else if (isinstance(obj, ["Iterator", "Generator"]))
|
else if (isinstance(obj, ["Iterator", "Generator"]))
|
||||||
;
|
;
|
||||||
|
else if (isinstance(obj, ["Map"]))
|
||||||
|
// This is stupid.
|
||||||
|
res = (r for (r of obj));
|
||||||
else if (ctypes && ctypes.CData && obj instanceof ctypes.CData) {
|
else if (ctypes && ctypes.CData && obj instanceof ctypes.CData) {
|
||||||
while (obj.constructor instanceof ctypes.PointerType)
|
while (obj.constructor instanceof ctypes.PointerType)
|
||||||
obj = obj.contents;
|
obj = obj.contents;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
|
// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
|
||||||
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
|
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
|
||||||
// Copyright (c) 2008-2013 Kris Maglione <maglione.k at Gmail>
|
// Copyright (c) 2008-2014 Kris Maglione <maglione.k at Gmail>
|
||||||
//
|
//
|
||||||
// This work is licensed for reuse under an MIT license. Details are
|
// This work is licensed for reuse under an MIT license. Details are
|
||||||
// given in the LICENSE.txt file included with this file.
|
// given in the LICENSE.txt file included with this file.
|
||||||
@@ -16,6 +16,7 @@ lazyRequire("contexts", ["Group"]);
|
|||||||
lazyRequire("io", ["io"]);
|
lazyRequire("io", ["io"]);
|
||||||
lazyRequire("finder", ["RangeFind"]);
|
lazyRequire("finder", ["RangeFind"]);
|
||||||
lazyRequire("overlay", ["overlay"]);
|
lazyRequire("overlay", ["overlay"]);
|
||||||
|
lazyRequire("promises", ["Promise", "promises"]);
|
||||||
lazyRequire("sanitizer", ["sanitizer"]);
|
lazyRequire("sanitizer", ["sanitizer"]);
|
||||||
lazyRequire("storage", ["File", "storage"]);
|
lazyRequire("storage", ["File", "storage"]);
|
||||||
lazyRequire("template", ["template"]);
|
lazyRequire("template", ["template"]);
|
||||||
@@ -68,6 +69,50 @@ var Buffer = Module("Buffer", {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The load context of the window bound to this buffer.
|
||||||
|
*/
|
||||||
|
get loadContext() sanitizer.getContext(this.win),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Content preference methods.
|
||||||
|
*/
|
||||||
|
prefs: Class.Memoize(() => ({
|
||||||
|
/**
|
||||||
|
* Returns a promise for the given preference name.
|
||||||
|
*
|
||||||
|
* @param {string} pref The name of the preference to return.
|
||||||
|
* @returns {Promise<string>}
|
||||||
|
*/
|
||||||
|
get: promises.withCallback(function get(callback, pref) {
|
||||||
|
services.contentPrefs.getByDomainAndName(
|
||||||
|
this.uri.host, pref, this.loadContext,
|
||||||
|
callback);
|
||||||
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a content preference for the given buffer.
|
||||||
|
*
|
||||||
|
* @param {string} pref The preference to set.
|
||||||
|
* @param {string} value The value to store.
|
||||||
|
*/
|
||||||
|
set: promises.withCallback(function set(callback, pref, value) {
|
||||||
|
services.contentPrefs.set(
|
||||||
|
this.uri.host, pref, value, this.loadContext,
|
||||||
|
callback);
|
||||||
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear a content preference for the given buffer.
|
||||||
|
*
|
||||||
|
* @param {string} pref The preference to clear.
|
||||||
|
*/
|
||||||
|
clear: promises.withCallback(function clear(callback, pref) {
|
||||||
|
services.contentPrefs.removeByDomainAndName(
|
||||||
|
this.uri.domain, pref, this.loadContext, callback);
|
||||||
|
}),
|
||||||
|
})),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a content preference for the given buffer.
|
* Gets a content preference for the given buffer.
|
||||||
*
|
*
|
||||||
@@ -77,10 +122,10 @@ var Buffer = Module("Buffer", {
|
|||||||
* @returns {string|number|boolean} The value of the preference, if
|
* @returns {string|number|boolean} The value of the preference, if
|
||||||
* callback is not provided.
|
* callback is not provided.
|
||||||
*/
|
*/
|
||||||
getPref: function getPref(pref, callback) {
|
getPref: deprecated("prefs.get", function getPref(pref, callback) {
|
||||||
services.contentPrefs.getPref(this.uri, pref,
|
services.contentPrefs.getPref(this.uri, pref,
|
||||||
sanitizer.getContext(this.win), callback);
|
this.loadContext, callback);
|
||||||
},
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a content preference for the given buffer.
|
* Sets a content preference for the given buffer.
|
||||||
@@ -88,20 +133,20 @@ var Buffer = Module("Buffer", {
|
|||||||
* @param {string} pref The preference to set.
|
* @param {string} pref The preference to set.
|
||||||
* @param {string} value The value to store.
|
* @param {string} value The value to store.
|
||||||
*/
|
*/
|
||||||
setPref: function setPref(pref, value) {
|
setPref: deprecated("prefs.set", function setPref(pref, value) {
|
||||||
services.contentPrefs.setPref(
|
services.contentPrefs.setPref(
|
||||||
this.uri, pref, value, sanitizer.getContext(this.win));
|
this.uri, pref, value, this.loadContext);
|
||||||
},
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear a content preference for the given buffer.
|
* Clear a content preference for the given buffer.
|
||||||
*
|
*
|
||||||
* @param {string} pref The preference to clear.
|
* @param {string} pref The preference to clear.
|
||||||
*/
|
*/
|
||||||
clearPref: function clearPref(pref) {
|
clearPref: deprecated("prefs.clear", function clearPref(pref) {
|
||||||
services.contentPrefs.removePref(
|
services.contentPrefs.removePref(
|
||||||
this.uri, pref, sanitizer.getContext(this.win));
|
this.uri, pref, this.loadContext);
|
||||||
},
|
}),
|
||||||
|
|
||||||
climbUrlPath: function climbUrlPath(count) {
|
climbUrlPath: function climbUrlPath(count) {
|
||||||
let { dactyl } = this.modules;
|
let { dactyl } = this.modules;
|
||||||
@@ -1244,12 +1289,12 @@ var Buffer = Module("Buffer", {
|
|||||||
if (prefs.get("browser.zoom.siteSpecific")) {
|
if (prefs.get("browser.zoom.siteSpecific")) {
|
||||||
var privacy = sanitizer.getContext(this.win);
|
var privacy = sanitizer.getContext(this.win);
|
||||||
if (value == 1) {
|
if (value == 1) {
|
||||||
this.clearPref("browser.content.full-zoom");
|
this.prefs.clear("browser.content.full-zoom");
|
||||||
this.clearPref("dactyl.content.full-zoom");
|
this.prefs.clear("dactyl.content.full-zoom");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.setPref("browser.content.full-zoom", value);
|
this.prefs.set("browser.content.full-zoom", value);
|
||||||
this.setPref("dactyl.content.full-zoom", fullZoom);
|
this.prefs.set("dactyl.content.full-zoom", fullZoom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1259,15 +1304,15 @@ var Buffer = Module("Buffer", {
|
|||||||
/**
|
/**
|
||||||
* Updates the zoom level of this buffer from a content preference.
|
* Updates the zoom level of this buffer from a content preference.
|
||||||
*/
|
*/
|
||||||
updateZoom: util.wrapCallback(function updateZoom() {
|
updateZoom: promises.task(function updateZoom() {
|
||||||
let uri = this.uri;
|
let uri = this.uri;
|
||||||
|
|
||||||
if (prefs.get("browser.zoom.siteSpecific")) {
|
if (prefs.get("browser.zoom.siteSpecific")) {
|
||||||
this.getPref("dactyl.content.full-zoom", (val) => {
|
let val = this.prefs.get("dactyl.content.full-zoom");
|
||||||
if (val != null && uri.equals(this.uri) && val != prefs.get("browser.zoom.full"))
|
|
||||||
[this.contentViewer.textZoom, this.contentViewer.fullZoom] =
|
if (val != null && uri.equals(this.uri) && val != prefs.get("browser.zoom.full"))
|
||||||
[this.contentViewer.fullZoom, this.contentViewer.textZoom];
|
[this.contentViewer.textZoom, this.contentViewer.fullZoom] =
|
||||||
});
|
[this.contentViewer.fullZoom, this.contentViewer.textZoom];
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|||||||
@@ -733,7 +733,7 @@ var CompletionContext = Class("CompletionContext", {
|
|||||||
let alias = (prop) => {
|
let alias = (prop) => {
|
||||||
context.__defineGetter__(prop, () => this[prop]);
|
context.__defineGetter__(prop, () => this[prop]);
|
||||||
context.__defineSetter__(prop, (val) => this[prop] = val);
|
context.__defineSetter__(prop, (val) => this[prop] = val);
|
||||||
}
|
};
|
||||||
alias("_cache");
|
alias("_cache");
|
||||||
alias("_completions");
|
alias("_completions");
|
||||||
alias("_generate");
|
alias("_generate");
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ var ConfigBase = Class("ConfigBase", {
|
|||||||
* initialization code. Must call superclass's init function.
|
* initialization code. Must call superclass's init function.
|
||||||
*/
|
*/
|
||||||
init: function init() {
|
init: function init() {
|
||||||
if (config.haveGecko("26"))
|
if (!config.haveGecko("26"))
|
||||||
this.modules.global = this.modules.global.filter(m => m != "downloads"); // FIXME
|
this.modules.global = this.modules.global.filter(m => m != "downloads"); // FIXME
|
||||||
|
|
||||||
this.loadConfig();
|
this.loadConfig();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2011-2013 Kris Maglione <maglione.k@gmail.com>
|
// Copyright (c) 2011-2014 Kris Maglione <maglione.k@gmail.com>
|
||||||
//
|
//
|
||||||
// This work is licensed for reuse under an MIT license. Details are
|
// This work is licensed for reuse under an MIT license. Details are
|
||||||
// given in the LICENSE.txt file included with this file.
|
// given in the LICENSE.txt file included with this file.
|
||||||
@@ -10,8 +10,10 @@ defineModule("downloads", {
|
|||||||
});
|
});
|
||||||
|
|
||||||
lazyRequire("overlay", ["overlay"]);
|
lazyRequire("overlay", ["overlay"]);
|
||||||
|
lazyRequire("promises", ["Task", "promises"]);
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/DownloadUtils.jsm", this);
|
lazyRequire("resource://gre/modules/Downloads.jsm", ["Downloads"]);
|
||||||
|
lazyRequire("resource://gre/modules/DownloadUtils.jsm", ["DownloadUtils"]);
|
||||||
|
|
||||||
var MAX_LOAD_TIME = 10 * 1000;
|
var MAX_LOAD_TIME = 10 * 1000;
|
||||||
|
|
||||||
@@ -22,8 +24,8 @@ var states = iter([v, k.slice(prefix.length).toLowerCase()]
|
|||||||
.toObject();
|
.toObject();
|
||||||
|
|
||||||
var Download = Class("Download", {
|
var Download = Class("Download", {
|
||||||
init: function init(id, list) {
|
init: function init(download, list) {
|
||||||
this.download = services.downloadManager.getDownload(id);
|
this.download = download;
|
||||||
this.list = list;
|
this.list = list;
|
||||||
|
|
||||||
this.nodes = {
|
this.nodes = {
|
||||||
@@ -39,11 +41,9 @@ var Download = Class("Download", {
|
|||||||
this.targetFile.path]]],
|
this.targetFile.path]]],
|
||||||
["td", { highlight: "DownloadState", key: "state" }],
|
["td", { highlight: "DownloadState", key: "state" }],
|
||||||
["td", { highlight: "DownloadButtons Buttons" },
|
["td", { highlight: "DownloadButtons Buttons" },
|
||||||
["a", { highlight: "Button", href: "javascript:0", key: "pause" }, _("download.action.Pause")],
|
["a", { highlight: "Button", href: "javascript:0", key: "stop" }, _("download.action.Stop")],
|
||||||
["a", { highlight: "Button", href: "javascript:0", key: "remove" }, _("download.action.Remove")],
|
["a", { highlight: "Button", href: "javascript:0", key: "remove" }, _("download.action.Remove")],
|
||||||
["a", { highlight: "Button", href: "javascript:0", key: "resume" }, _("download.action.Resume")],
|
["a", { highlight: "Button", href: "javascript:0", key: "resume" }, _("download.action.Resume")],
|
||||||
["a", { highlight: "Button", href: "javascript:0", key: "retry" }, _("download.action.Retry")],
|
|
||||||
["a", { highlight: "Button", href: "javascript:0", key: "cancel" }, _("download.action.Cancel")],
|
|
||||||
["a", { highlight: "Button", href: "javascript:0", key: "delete" }, _("download.action.Delete")]],
|
["a", { highlight: "Button", href: "javascript:0", key: "delete" }, _("download.action.Delete")]],
|
||||||
["td", { highlight: "DownloadProgress", key: "progress" },
|
["td", { highlight: "DownloadProgress", key: "progress" },
|
||||||
["span", { highlight: "DownloadProgressHave", key: "progressHave" }],
|
["span", { highlight: "DownloadProgressHave", key: "progressHave" }],
|
||||||
@@ -53,8 +53,8 @@ var Download = Class("Download", {
|
|||||||
["td", { highlight: "DownloadSpeed", key: "speed" }],
|
["td", { highlight: "DownloadSpeed", key: "speed" }],
|
||||||
["td", { highlight: "DownloadTime", key: "time" }],
|
["td", { highlight: "DownloadTime", key: "time" }],
|
||||||
["td", {},
|
["td", {},
|
||||||
["a", { highlight: "DownloadSource", key: "source", href: this.source.spec },
|
["a", { highlight: "DownloadSource", key: "source", href: this.source.url },
|
||||||
this.source.spec]]],
|
this.source.url]]],
|
||||||
this.list.document, this.nodes);
|
this.list.document, this.nodes);
|
||||||
|
|
||||||
this.nodes.launch.addEventListener("click", (event) => {
|
this.nodes.launch.addEventListener("click", (event) => {
|
||||||
@@ -68,21 +68,22 @@ var Download = Class("Download", {
|
|||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get active() !this.stopped,
|
||||||
|
|
||||||
|
get targetFile() File(this.download.target.path),
|
||||||
|
|
||||||
|
get displayName() this.targetFile.leafName,
|
||||||
|
|
||||||
get status() states[this.state],
|
get status() states[this.state],
|
||||||
|
|
||||||
inState: function inState(states) states.indexOf(this.status) >= 0,
|
inState: function inState(states) states.indexOf(this.status) >= 0,
|
||||||
|
|
||||||
get alive() this.inState(["downloading", "notstarted", "paused", "queued", "scanning"]),
|
|
||||||
|
|
||||||
allowedCommands: Class.Memoize(function () let (self = this) ({
|
allowedCommands: Class.Memoize(function () let (self = this) ({
|
||||||
get cancel() self.cancelable && self.inState(["downloading", "paused", "starting"]),
|
get delete() !self.active && (self.targetFile.exists() || self.hasPartialData),
|
||||||
get delete() !this.cancel && self.targetFile.exists(),
|
get launch() self.targetFile.exists() && self.succeeded,
|
||||||
get launch() self.targetFile.exists() && self.inState(["finished"]),
|
get stop() self.active,
|
||||||
get pause() self.inState(["downloading"]),
|
get remove() !self.active,
|
||||||
get remove() self.inState(["blocked_parental", "blocked_policy",
|
get resume() self.canceled
|
||||||
"canceled", "dirty", "failed", "finished"]),
|
|
||||||
get resume() self.resumable && self.inState(["paused"]),
|
|
||||||
get retry() self.inState(["canceled", "failed"])
|
|
||||||
})),
|
})),
|
||||||
|
|
||||||
command: function command(name) {
|
command: function command(name) {
|
||||||
@@ -91,15 +92,16 @@ var Download = Class("Download", {
|
|||||||
|
|
||||||
if (Set.has(this.commands, name))
|
if (Set.has(this.commands, name))
|
||||||
this.commands[name].call(this);
|
this.commands[name].call(this);
|
||||||
else
|
|
||||||
services.downloadManager[name + "Download"](this.id);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
commands: {
|
commands: {
|
||||||
delete: function delete_() {
|
delete: promises.task(function delete_() {
|
||||||
this.targetFile.remove(false);
|
if (this.hasPartialData)
|
||||||
|
yield this.removePartialData();
|
||||||
|
else if (self.targetFile.exists())
|
||||||
|
this.targetFile.remove(false);
|
||||||
this.updateStatus();
|
this.updateStatus();
|
||||||
},
|
}),
|
||||||
launch: function launch() {
|
launch: function launch() {
|
||||||
// Behavior mimics that of the builtin Download Manager.
|
// Behavior mimics that of the builtin Download Manager.
|
||||||
function action() {
|
function action() {
|
||||||
@@ -127,18 +129,28 @@ var Download = Class("Download", {
|
|||||||
});
|
});
|
||||||
else
|
else
|
||||||
action.call(this);
|
action.call(this);
|
||||||
}
|
},
|
||||||
|
resume: function resume() {
|
||||||
|
this.download.start();
|
||||||
|
},
|
||||||
|
remove: promises.task(function remove() {
|
||||||
|
yield this.list.list.remove(this.download);
|
||||||
|
yield this.download.finalize(true);
|
||||||
|
}),
|
||||||
|
stop: function stop() {
|
||||||
|
this.download.cancel();
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
_compare: {
|
_compare: {
|
||||||
active: (a, b) => a.alive - b.alive,
|
active: (a, b) => a.active - b.active,
|
||||||
complete: (a, b) => a.percentComplete - b.percentComplete,
|
complete: (a, b) => a.percentComplete - b.percentComplete,
|
||||||
date: (a, b) => a.startTime - b.startTime,
|
date: (a, b) => a.startTime - b.startTime,
|
||||||
filename: (a, b) => String.localeCompare(a.targetFile.leafName, b.targetFile.leafName),
|
filename: (a, b) => String.localeCompare(a.targetFile.leafName, b.targetFile.leafName),
|
||||||
size: (a, b) => a.size - b.size,
|
size: (a, b) => a.totalBytes - b.totalBytes,
|
||||||
speed: (a, b) => a.speed - b.speed,
|
speed: (a, b) => a.speed - b.speed,
|
||||||
time: (a, b) => a.timeRemaining - b.timeRemaining,
|
time: (a, b) => a.timeRemaining - b.timeRemaining,
|
||||||
url: (a, b) => String.localeCompare(a.source.spec, b.source.spec)
|
url: (a, b) => String.localeCompare(a.source.url, b.source.url)
|
||||||
},
|
},
|
||||||
|
|
||||||
compare: function compare(other) values(this.list.sortOrder).map(function (order) {
|
compare: function compare(other) values(this.list.sortOrder).map(function (order) {
|
||||||
@@ -152,17 +164,17 @@ var Download = Class("Download", {
|
|||||||
updateProgress: function updateProgress() {
|
updateProgress: function updateProgress() {
|
||||||
let self = this.__proto__;
|
let self = this.__proto__;
|
||||||
|
|
||||||
if (this.amountTransferred === this.size) {
|
if (!this.active) {
|
||||||
this.nodes.speed.textContent = "";
|
this.nodes.speed.textContent = "";
|
||||||
this.nodes.time.textContent = "";
|
this.nodes.time.textContent = "";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.nodes.speed.textContent = util.formatBytes(this.speed, 1, true) + "/s";
|
this.nodes.speed.textContent = util.formatBytes(this.speed, 1, true) + "/s";
|
||||||
|
|
||||||
if (this.speed == 0 || this.size == 0)
|
if (this.speed == 0 || !this.hasProgress)
|
||||||
this.nodes.time.textContent = _("download.unknown");
|
this.nodes.time.textContent = _("download.unknown");
|
||||||
else {
|
else {
|
||||||
let seconds = (this.size - this.amountTransferred) / this.speed;
|
let seconds = (this.totalBytes - this.currentBytes) / this.speed;
|
||||||
[, self.timeRemaining] = DownloadUtils.getTimeLeft(seconds, this.timeRemaining);
|
[, self.timeRemaining] = DownloadUtils.getTimeLeft(seconds, this.timeRemaining);
|
||||||
if (this.timeRemaining)
|
if (this.timeRemaining)
|
||||||
this.nodes.time.textContent = util.formatSeconds(this.timeRemaining);
|
this.nodes.time.textContent = util.formatSeconds(this.timeRemaining);
|
||||||
@@ -171,17 +183,20 @@ var Download = Class("Download", {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let total = this.nodes.progressTotal.textContent = this.size || !this.nActive ? util.formatBytes(this.size, 1, true)
|
let total = this.nodes.progressTotal.textContent =
|
||||||
: _("download.unknown");
|
this.hasProgress && (this.totalBytes || !this.nActive)
|
||||||
let suffix = RegExp(/( [a-z]+)?$/i.exec(total)[0] + "$");
|
? util.formatBytes(this.totalBytes, 1, true)
|
||||||
this.nodes.progressHave.textContent = util.formatBytes(this.amountTransferred, 1, true).replace(suffix, "");
|
: _("download.unknown");
|
||||||
|
|
||||||
this.nodes.percent.textContent = this.size ? Math.round(this.amountTransferred * 100 / this.size) + "%" : "";
|
let suffix = RegExp(/( [a-z]+)?$/i.exec(total)[0] + "$");
|
||||||
|
this.nodes.progressHave.textContent = util.formatBytes(this.currentBytes, 1, true).replace(suffix, "");
|
||||||
|
|
||||||
|
this.nodes.percent.textContent = this.hasProgress ? this.progress + "%" : "";
|
||||||
},
|
},
|
||||||
|
|
||||||
updateStatus: function updateStatus() {
|
updateStatus: function updateStatus() {
|
||||||
|
|
||||||
this.nodes.row[this.alive ? "setAttribute" : "removeAttribute"]("active", "true");
|
this.nodes.row[this.active ? "setAttribute" : "removeAttribute"]("active", "true");
|
||||||
|
|
||||||
this.nodes.row.setAttribute("status", this.status);
|
this.nodes.row.setAttribute("status", this.status);
|
||||||
this.nodes.state.textContent = util.capitalize(this.status);
|
this.nodes.state.textContent = util.capitalize(this.status);
|
||||||
@@ -193,14 +208,6 @@ var Download = Class("Download", {
|
|||||||
this.updateProgress();
|
this.updateProgress();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Object.keys(XPCOMShim([Ci.nsIDownload])).forEach(function (key) {
|
|
||||||
if (!(key in Download.prototype))
|
|
||||||
Object.defineProperty(Download.prototype, key, {
|
|
||||||
get: function get() this.download[key],
|
|
||||||
set: function set(val) this.download[key] = val,
|
|
||||||
configurable: true
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
var DownloadList = Class("DownloadList",
|
var DownloadList = Class("DownloadList",
|
||||||
XPCOM([Ci.nsIDownloadProgressListener,
|
XPCOM([Ci.nsIDownloadProgressListener,
|
||||||
@@ -213,12 +220,13 @@ var DownloadList = Class("DownloadList",
|
|||||||
this.nodes = {
|
this.nodes = {
|
||||||
commandTarget: this
|
commandTarget: this
|
||||||
};
|
};
|
||||||
this.downloads = {};
|
this.downloads = Map();
|
||||||
},
|
},
|
||||||
|
|
||||||
cleanup: function cleanup() {
|
cleanup: function cleanup() {
|
||||||
this.observe.unregister();
|
if (this.list)
|
||||||
services.downloadManager.removeListener(this);
|
this.list.removeView(this);
|
||||||
|
this.dead = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
message: Class.Memoize(function () {
|
message: Class.Memoize(function () {
|
||||||
@@ -258,40 +266,44 @@ var DownloadList = Class("DownloadList",
|
|||||||
this.index = Array.indexOf(this.nodes.list.childNodes,
|
this.index = Array.indexOf(this.nodes.list.childNodes,
|
||||||
this.nodes.head);
|
this.nodes.head);
|
||||||
|
|
||||||
let start = Date.now();
|
Task.spawn(function () {
|
||||||
for (let row in iter(services.downloadManager.DBConnection
|
this.list = yield Downloads.getList(Downloads.ALL);
|
||||||
.createStatement("SELECT id FROM moz_downloads"))) {
|
|
||||||
if (Date.now() - start > MAX_LOAD_TIME) {
|
|
||||||
util.dactyl.warn(_("download.givingUpAfter", (Date.now() - start) / 1000));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
this.addDownload(row.id);
|
|
||||||
}
|
|
||||||
this.update();
|
|
||||||
|
|
||||||
util.addObserver(this);
|
let start = Date.now();
|
||||||
services.downloadManager.addListener(this);
|
for (let download of yield this.list.getAll()) {
|
||||||
|
if (Date.now() - start > MAX_LOAD_TIME) {
|
||||||
|
util.dactyl.warn(_("download.givingUpAfter", (Date.now() - start) / 1000));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.addDownload(download);
|
||||||
|
}
|
||||||
|
this.update();
|
||||||
|
|
||||||
|
if (!this.dead)
|
||||||
|
this.list.addView(this);
|
||||||
|
}.bind(this));
|
||||||
return this.nodes.list;
|
return this.nodes.list;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
addDownload: function addDownload(id) {
|
addDownload: function addDownload(download) {
|
||||||
if (!(id in this.downloads)) {
|
if (!this.downloads.has(download)) {
|
||||||
let download = Download(id, this);
|
download = Download(download, this);
|
||||||
if (this.filter && download.displayName.indexOf(this.filter) === -1)
|
if (this.filter && download.displayName.indexOf(this.filter) === -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.downloads[id] = download;
|
this.downloads.set(download.download, download);
|
||||||
let index = values(this.downloads).sort((a, b) => a.compare(b))
|
let index = values(this.downloads).toArray()
|
||||||
.indexOf(download);
|
.sort((a, b) => a.compare(b))
|
||||||
|
.indexOf(download);
|
||||||
|
|
||||||
this.nodes.list.insertBefore(download.nodes.row,
|
this.nodes.list.insertBefore(download.nodes.row,
|
||||||
this.nodes.list.childNodes[index + this.index + 1]);
|
this.nodes.list.childNodes[index + this.index + 1]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
removeDownload: function removeDownload(id) {
|
removeDownload: function removeDownload(download) {
|
||||||
if (id in this.downloads) {
|
if (this.downloads.has(download)) {
|
||||||
this.nodes.list.removeChild(this.downloads[id].nodes.row);
|
this.nodes.list.removeChild(this.downloads.get(download).nodes.row);
|
||||||
delete this.downloads[id];
|
delete this.downloads.delete(download);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -301,17 +313,17 @@ var DownloadList = Class("DownloadList",
|
|||||||
},
|
},
|
||||||
|
|
||||||
allowedCommands: Class.Memoize(function () let (self = this) ({
|
allowedCommands: Class.Memoize(function () let (self = this) ({
|
||||||
get clear() values(self.downloads).some(dl => dl.allowedCommands.remove)
|
get clear() iter(self.downloads.values()).some(dl => dl.allowedCommands.remove)
|
||||||
})),
|
})),
|
||||||
|
|
||||||
commands: {
|
commands: {
|
||||||
clear: function () {
|
clear: function () {
|
||||||
services.downloadManager.cleanUp();
|
this.list.removeFinished();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
sort: function sort() {
|
sort: function sort() {
|
||||||
let list = values(this.downloads).sort((a, b) => a.compare(b));
|
let list = iter(this.downloads.values()).sort((a, b) => a.compare(b));
|
||||||
|
|
||||||
for (let [i, download] in iter(list))
|
for (let [i, download] in iter(list))
|
||||||
if (this.nodes.list.childNodes[i + 1] != download.nodes.row)
|
if (this.nodes.list.childNodes[i + 1] != download.nodes.row)
|
||||||
@@ -335,16 +347,19 @@ var DownloadList = Class("DownloadList",
|
|||||||
timeRemaining: Infinity,
|
timeRemaining: Infinity,
|
||||||
|
|
||||||
updateProgress: function updateProgress() {
|
updateProgress: function updateProgress() {
|
||||||
let downloads = values(this.downloads).toArray();
|
let downloads = iter(this.downloads.values()).toArray();
|
||||||
let active = downloads.filter(d => d.alive);
|
let active = downloads.filter(d => d.active);
|
||||||
|
|
||||||
let self = Object.create(this);
|
let self = Object.create(this);
|
||||||
for (let prop in values(["amountTransferred", "size", "speed", "timeRemaining"]))
|
for (let prop in values(["currentBytes", "totalBytes", "speed", "timeRemaining"]))
|
||||||
this[prop] = active.reduce((acc, dl) => dl[prop] + acc, 0);
|
this[prop] = active.reduce((acc, dl) => dl[prop] + acc, 0);
|
||||||
|
|
||||||
|
this.hasProgress = active.every(d => d.hasProgress);
|
||||||
|
this.progress = Math.round((this.currentBytes / this.totalBytes) * 100);
|
||||||
|
this.nActive = active.length;
|
||||||
|
|
||||||
Download.prototype.updateProgress.call(self);
|
Download.prototype.updateProgress.call(self);
|
||||||
|
|
||||||
this.nActive = active.length;
|
|
||||||
if (active.length)
|
if (active.length)
|
||||||
this.nodes.total.textContent = _("download.nActive", active.length);
|
this.nodes.total.textContent = _("download.nActive", active.length);
|
||||||
else for (let key in values(["total", "percent", "speed", "time"]))
|
else for (let key in values(["total", "percent", "speed", "time"]))
|
||||||
@@ -354,68 +369,87 @@ var DownloadList = Class("DownloadList",
|
|||||||
this.sort();
|
this.sort();
|
||||||
},
|
},
|
||||||
|
|
||||||
observers: {
|
onDownloadAdded: function onDownloadAdded(download) {
|
||||||
"download-manager-remove-download": function (id) {
|
this.addDownload(download);
|
||||||
if (id == null)
|
|
||||||
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.modules.mow.resize(false);
|
||||||
this.update();
|
this.nodes.list.scrollIntoView(false);
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onDownloadStateChange: function (state, download) {
|
onDownloadRemoved: function onDownloadRemoved(download) {
|
||||||
try {
|
this.removeDownload(download);
|
||||||
if (download.id in this.downloads)
|
},
|
||||||
this.downloads[download.id].updateStatus();
|
|
||||||
else {
|
onDownloadChanged: function onDownloadChanged(download) {
|
||||||
this.addDownload(download.id);
|
if (this.downloads.has(download)) {
|
||||||
|
download = this.downloads.get(download)
|
||||||
|
|
||||||
|
download.updateStatus();
|
||||||
|
download.updateProgress();
|
||||||
|
|
||||||
this.modules.mow.resize(false);
|
|
||||||
this.nodes.list.scrollIntoView(false);
|
|
||||||
}
|
|
||||||
this.update();
|
this.update();
|
||||||
|
|
||||||
if (this.shouldSort("active"))
|
if (this.shouldSort("active"))
|
||||||
this.sort();
|
this.sort();
|
||||||
}
|
}
|
||||||
catch (e) {
|
|
||||||
util.reportError(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onProgressChange: function (webProgress, request,
|
|
||||||
curProgress, maxProgress,
|
|
||||||
curTotalProgress, maxTotalProgress,
|
|
||||||
download) {
|
|
||||||
try {
|
|
||||||
if (download.id in this.downloads)
|
|
||||||
this.downloads[download.id].updateProgress();
|
|
||||||
this.updateProgress();
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
util.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
["canceled",
|
||||||
|
"contentType",
|
||||||
|
"currentBytes",
|
||||||
|
"error",
|
||||||
|
"hasPartialData",
|
||||||
|
"hasProgress",
|
||||||
|
"launchWhenSucceeded",
|
||||||
|
"launcherPath",
|
||||||
|
"progress",
|
||||||
|
"saver",
|
||||||
|
"source",
|
||||||
|
"speed",
|
||||||
|
"startTime",
|
||||||
|
"stopped",
|
||||||
|
"succeeded",
|
||||||
|
"target",
|
||||||
|
"totalBytes",
|
||||||
|
"tryToKeepPartialData"].forEach(key => {
|
||||||
|
if (!(key in Download.prototype))
|
||||||
|
Object.defineProperty(Download.prototype, key, {
|
||||||
|
get: function get() this.download[key],
|
||||||
|
set: function set(val) this.download[key] = val,
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
var Downloads = Module("downloads", XPCOM(Ci.nsIDownloadProgressListener), {
|
|
||||||
|
var Downloads_ = Module("downloads", XPCOM(Ci.nsIDownloadProgressListener), {
|
||||||
init: function () {
|
init: function () {
|
||||||
services.downloadManager.addListener(this);
|
Downloads.getList(Downloads.ALL).then(list => {
|
||||||
|
this.list = list;
|
||||||
|
if (!this.dead)
|
||||||
|
this.list.addView(this);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
cleanup: function destroy() {
|
cleanup: function destroy() {
|
||||||
services.downloadManager.removeListener(this);
|
if (this.list)
|
||||||
|
this.list.removeView(this);
|
||||||
|
this.dead = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
onDownloadStateChange: function (state, download) {
|
onDownloadAdded: function onDownloadAdded(download) {
|
||||||
if (download.state == services.downloadManager.DOWNLOAD_FINISHED) {
|
},
|
||||||
let url = download.source.spec;
|
|
||||||
let title = download.displayName;
|
onDownloadRemoved: function onDownloadRemoved(download) {
|
||||||
let file = download.targetFile.path;
|
},
|
||||||
let size = download.size;
|
|
||||||
|
onDownloadChanged: function onDownloadChanged(download) {
|
||||||
|
if (download.succeeded) {
|
||||||
|
let target = File(download.target.path);
|
||||||
|
|
||||||
|
let url = download.source.url;
|
||||||
|
let title = target.leafName;
|
||||||
|
let file = target.path;
|
||||||
|
let size = download.totalBytes;
|
||||||
|
|
||||||
overlay.modules.forEach(function (modules) {
|
overlay.modules.forEach(function (modules) {
|
||||||
modules.dactyl.echomsg({ domains: [util.getHost(url)], message: _("io.downloadFinished", title, file) },
|
modules.dactyl.echomsg({ domains: [util.getHost(url)], message: _("io.downloadFinished", title, file) },
|
||||||
@@ -451,7 +485,7 @@ var Downloads = Module("downloads", XPCOM(Ci.nsIDownloadProgressListener), {
|
|||||||
|
|
||||||
commands.add(["dlc[lear]"],
|
commands.add(["dlc[lear]"],
|
||||||
"Clear completed downloads",
|
"Clear completed downloads",
|
||||||
function (args) { services.downloadManager.cleanUp(); });
|
function (args) { downloads.list.removeFinished(); });
|
||||||
},
|
},
|
||||||
options: function initOptions(dactyl, modules, window) {
|
options: function initOptions(dactyl, modules, window) {
|
||||||
const { options } = modules;
|
const { options } = modules;
|
||||||
|
|||||||
@@ -336,9 +336,6 @@ var JavaScript = Module("javascript", {
|
|||||||
_complete: function (objects, key, compl, string, last) {
|
_complete: function (objects, key, compl, string, last) {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
if (!getOwnPropertyNames && !services.debugger.isOn && !this.context.message)
|
|
||||||
this.context.message = /*L*/"For better completion data, please enable the JavaScript debugger (:set jsdebugger)";
|
|
||||||
|
|
||||||
let base = this.context.fork("js", this._top.offset);
|
let base = this.context.fork("js", this._top.offset);
|
||||||
base.forceAnchored = true;
|
base.forceAnchored = true;
|
||||||
base.filter = last == null ? key : string;
|
base.filter = last == null ? key : string;
|
||||||
|
|||||||
48
common/modules/promises.jsm
Normal file
48
common/modules/promises.jsm
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
// Copyright (c) 2014 Kris Maglione <maglione.k at Gmail>
|
||||||
|
//
|
||||||
|
// This work is licensed for reuse under an MIT license. Details are
|
||||||
|
// given in the LICENSE.txt file included with this file.
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
defineModule("promises", {
|
||||||
|
exports: ["Promise", "Task", "promises"],
|
||||||
|
require: []
|
||||||
|
});
|
||||||
|
|
||||||
|
lazyRequire("resource://gre/modules/Promise.jsm", ["Promise"]);
|
||||||
|
lazyRequire("resource://gre/modules/Task.jsm", ["Task"]);
|
||||||
|
|
||||||
|
var Promises = Module("Promises", {
|
||||||
|
/**
|
||||||
|
* Wraps the given function so that each call spawns a Task.
|
||||||
|
*
|
||||||
|
* @param {function} fn The function to wrap.
|
||||||
|
* @returns {function}
|
||||||
|
*/
|
||||||
|
task: function task(fn) {
|
||||||
|
return function task_(...args) {
|
||||||
|
return Task.spawn(fn.bind.apply(fn, [this].concat(args)));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps the given function so that its first argument is a
|
||||||
|
* callback which, when called, resolves the returned promise.
|
||||||
|
*
|
||||||
|
* @param {function} fn The function to wrap.
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
withCallback: function withCallback(fn) {
|
||||||
|
return function wrapper(...args) {
|
||||||
|
let deferred = Promise.defer();
|
||||||
|
function callback(arg) {
|
||||||
|
deferred.resolve(arg);
|
||||||
|
}
|
||||||
|
return fn.apply(this, [callback].concat(args));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
endModule();
|
||||||
|
|
||||||
|
// vim: set fdm=marker sw=4 sts=4 ts=8 et ft=javascript:
|
||||||
Reference in New Issue
Block a user