// Copyright (c) 2006-2008 by Martin Stubenschrott <stubenschrott@vimperator.org>
// Copyright (c) 2007-2011 by Doug Kearns <dougkearns@gmail.com>
-// Copyright (c) 2008-2012 Kris Maglione <maglione.k@gmail.com>
+// Copyright (c) 2008-2014 Kris Maglione <maglione.k@gmail.com>
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
}
},
-
observers: {
"dactyl-cleanup": function dactyl_cleanup(subject, reason) {
let modules = dactyl.modules;
&& !item.hidden
&& !/rdf:http:/.test(item.getAttribute("label"))) { // FIXME
item.dactylPath = parent + item.getAttribute("label");
- if (!targetPath || targetPath.indexOf(item.dactylPath) == 0)
+ if (!targetPath || targetPath.startsWith(item.dactylPath))
items.push(item);
}
else {
let path = parent;
if (item.localName == "menu")
path += item.getAttribute("label") + ".";
- if (!targetPath || targetPath.indexOf(path) == 0)
+ if (!targetPath || targetPath.startsWith(path))
addChildren(item, path);
}
}
registerObservers: function registerObservers(obj, prop) {
for (let [signal, func] in Iterator(obj[prop || "signals"]))
- this.registerObserver(signal, obj.closure(func), false);
+ this.registerObserver(signal, func.bind(obj), false);
},
unregisterObserver: function unregisterObserver(type, callback) {
if (type in this._observers)
- this._observers[type] = this._observers[type].filter(function (c) c.get() != callback);
+ this._observers[type] = this._observers[type].filter(c => c.get() != callback);
},
applyTriggerObserver: function triggerObserver(type, args) {
if (type in this._observers)
- this._observers[type] = this._observers[type].filter(function (callback) {
- if (callback.get()) {
- try {
- try {
- callback.get().apply(null, args);
- }
- catch (e if e.message == "can't wrap XML objects") {
- // Horrible kludge.
- callback.get().apply(null, [String(args[0])].concat(args.slice(1)));
- }
- }
- catch (e) {
- dactyl.reportError(e);
- }
+ this._observers[type] = this._observers[type]
+ .filter(callback => {
+ callback = callback.get();
+ if (callback) {
+ util.trapErrors(() => callback.apply(null, args));
return true;
}
});
},
- triggerObserver: function triggerObserver(type) {
- return this.applyTriggerObserver(type, Array.slice(arguments, 1));
+ triggerObserver: function triggerObserver(type, ...args) {
+ return this.applyTriggerObserver(type, args);
},
addUsageCommand: function (params) {
let name = commands.add(params.name, params.description,
function (args) {
let results = array(params.iterate(args))
- .sort(function (a, b) String.localeCompare(a.name, b.name));
+ .sort((a, b) => String.localeCompare(a.name, b.name));
- let filters = args.map(function (arg) let (re = util.regexp.escape(arg))
+ let filters = args.map(arg => let (re = util.regexp.escape(arg))
util.regexp("\\b" + re + "\\b|(?:^|[()\\s])" + re + "(?:$|[()\\s])", "i"));
if (filters.length)
- results = results.filter(function (item) filters.every(function (re) keys(item).some(re.closure.test)));
+ results = results.filter(item => filters.every(re => keys(item).some(re.bound.test)));
commandline.commandOutput(
template.usage(results, params.format));
if (params.index)
this.indices[params.index] = function () {
let results = array((params.iterateIndex || params.iterate).call(params, commands.get(name).newArgs()))
- .array.sort(function (a, b) String.localeCompare(a.name, b.name));
+ .array.sort((a, b) => String.localeCompare(a.name, b.name));
- let haveTag = Set.has(help.tags);
for (let obj in values(results)) {
let res = dactyl.generateHelp(obj, null, null, true);
- if (!haveTag(obj.helpTag))
+ if (!hasOwnProperty(help.tags, obj.helpTag))
res[0][1].tag = obj.helpTag;
yield res;
},
dump: deprecated("util.dump",
- { get: function dump() util.closure.dump }),
+ { get: function dump() util.bound.dump }),
dumpStack: deprecated("util.dumpStack",
- { get: function dumpStack() util.closure.dumpStack }),
+ { get: function dumpStack() util.bound.dumpStack }),
/**
* Outputs a plain message to the command line.
* should be loaded.
*/
loadScript: function loadScript(uri, context) {
+ let prefix = "literal:" + uri + ":";
+ cache.flush(s => s.startsWith(prefix));
+ delete literal.files[uri];
JSMLoader.loadSubScript(uri, context, File.defaultEncoding);
},
userEval: function userEval(str, context, fileName, lineNumber) {
- let ctxt;
- if (jsmodules.__proto__ != window && jsmodules.__proto__ != XPCNativeWrapper(window) &&
- jsmodules.isPrototypeOf(context))
- str = "with (window) { with (modules) { (this.eval || eval)(" + str.quote() + ") } }";
+ let ctxt,
+ info = contexts.context;
- let info = contexts.context;
if (fileName == null)
if (info)
({ file: fileName, line: lineNumber, context: ctxt }) = info;
if (fileName && fileName[0] == "[")
fileName = "dactyl://command-line/";
else if (!context)
- context = ctxt || _userContext;
-
- if (isinstance(context, ["Sandbox"]))
- return Cu.evalInSandbox(str, context, "1.8", fileName, lineNumber);
+ context = ctxt || userContext;
if (!context)
context = userContext || ctxt;
+ if (isinstance(context, ["Sandbox"]))
+ return Cu.evalInSandbox(str, context, "1.8", fileName, lineNumber);
+
if (services.has("dactyl") && services.dactyl.evalInContext)
return services.dactyl.evalInContext(str, context, fileName, lineNumber);
* Acts like the Function builtin, but the code executes in the
* userContext global.
*/
- userFunc: function userFunc() {
+ userFunc: function userFunc(...args) {
return this.userEval(
- "(function userFunction(" + Array.slice(arguments, 0, -1).join(", ") + ")" +
- " { " + arguments[arguments.length - 1] + " })");
+ "(function userFunction(" + args.slice(0, -1).join(", ") + ")" +
+ " { " + args.pop() + " })");
},
/**
* @param {boolean} silent Whether the command should be echoed on the
* command line.
*/
- execute: function execute(str, modifiers, silent) {
+ execute: function execute(str, modifiers={}, silent=false) {
// skip comments and blank lines
if (/^\s*("|$)/.test(str))
return;
- modifiers = modifiers || {};
-
if (!silent)
commands.lastCommand = str.replace(/^\s*:\s*/, "");
let res = true;
if (win.frameElement)
win.frameElement.blur();
// Grr.
- if (content.document.activeElement instanceof HTMLIFrameElement)
+ if (content.document.activeElement instanceof Ci.nsIDOMHTMLIFrameElement)
content.document.activeElement.blur();
});
}
* @param {string} feature The feature name.
* @returns {boolean}
*/
- has: function has(feature) Set.has(config.features, feature),
+ has: function has(feature) config.has(feature),
/**
* @private
}
},
- help: deprecated("help.help", { get: function help() modules.help.closure.help }),
- findHelp: deprecated("help.findHelp", { get: function findHelp() help.closure.findHelp }),
+ help: deprecated("help.help", { get: function help() modules.help.bound.help }),
+ findHelp: deprecated("help.findHelp", { get: function findHelp() help.bound.findHelp }),
/**
* @private
let args = null;
if (obj instanceof Command) {
- link = function (cmd) ["ex", {}, cmd];
+ link = cmd => ["ex", {}, cmd];
args = obj.parseArgs("", CompletionContext(str || ""));
- tag = function (cmd) DOM.DOMString(":" + cmd);
- spec = function (cmd) [
+ tag = cmd => DOM.DOMString(":" + cmd);
+ spec = cmd => [
obj.count ? ["oa", {}, "count"] : [],
cmd,
obj.bang ? ["oa", {}, "!"] : []
];
}
else if (obj instanceof Map) {
- spec = function (map) obj.count ? [["oa", {}, "count"], map] : DOM.DOMString(map);
- tag = function (map) [
+ spec = map => (obj.count ? [["oa", {}, "count"], map]
+ : DOM.DOMString(map));
+ tag = map => [
let (c = obj.modes[0].char) c ? c + "_" : "",
map
- ]
- link = function (map) {
+ ];
+ link = map => {
let [, mode, name, extra] = /^(?:(.)_)?(?:<([^>]+)>)?(.*)$/.exec(map);
let k = ["k", {}, extra];
if (name)
};
}
else if (obj instanceof Option) {
- spec = function () template.map(obj.names, tag, " ");
- tag = function (name) DOM.DOMString("'" + name + "'");
- link = function (opt, name) ["o", {}, name];
+ spec = () => template.map(obj.names, tag, " ");
+ tag = name => DOM.DOMString("'" + name + "'");
+ link = (opt, name) => ["o", {}, name];
args = { value: "", values: [] };
}
let description = ["description", {},
obj.description ? ["p", {}, template.linkifyHelp(obj.description.replace(/\.?$/, "."), true)] : "",
extraHelp ? extraHelp : "",
- !(extraHelp || obj.description) ? ["p", {}, /*L*/ "Sorry, no help available."] : ""]
+ !(extraHelp || obj.description) ? ["p", {}, /*L*/ "Sorry, no help available."] : ""];
res.push(
["item", {},
let (name = (obj.specs || obj.names)[0])
spec(template.highlightRegexp(tag(name),
/\[(.*?)\]/g,
- function (m, n0) ["oa", {}, n0]),
+ (m, n0) => ["oa", {}, n0]),
name)],
!obj.type ? "" : [
["type", {}, obj.type],
}
if (obj.completer && false)
- add(completion._runCompleter(obj.closure.completer, "", null, args).items
- .map(function (i) [i.text, i.description]));
+ add(completion._runCompleter(obj.bound.completer, "", null, args).items
+ .map(i => [i.text, i.description]));
- if (obj.options && obj.options.some(function (o) o.description) && false)
- add(obj.options.filter(function (o) o.description)
- .map(function (o) [
+ if (obj.options && obj.options.some(o => o.description) && false)
+ add(obj.options.filter(o => o.description)
+ .map(o => [
o.names[0],
[o.description,
o.names.length == 1 ? "" :
["", " (short name: ",
- template.map(o.names.slice(1), function (n) ["em", {}, n], ", "),
+ template.map(o.names.slice(1),
+ n => ["em", {}, n],
+ ", "),
")"]]
]));
},
events: {
+ beforecustomization: function onbeforecustomization(event) {
+ // Show navigation bar on Australis, where it's not supposed
+ // to be collapsible, and is therefore not handled by
+ // builtin code.
+ if ("CustomizableUI" in window)
+ this.setNodeVisible(document.getElementById("nav-bar"),
+ true);
+ },
+
+ aftercustomization: function onaftercustomization(event) {
+ // Restore toolbar states.
+ options["guioptions"] = options["guioptions"];
+ },
+
click: function onClick(event) {
let elem = event.originalTarget;
* tabs.
* @returns {boolean}
*/
- open: function open(urls, params, force) {
+ open: function open(urls, params={}, force=false) {
if (typeof urls == "string")
urls = dactyl.parseURLs(urls);
if (urls.length > prefs.get("browser.tabs.maxOpenBeforeWarn", 20) && !force)
- return commandline.input(_("dactyl.prompt.openMany", urls.length) + " ",
- function (resp) {
+ return commandline.input(_("dactyl.prompt.openMany", urls.length) + " ")
+ .then(function (resp) {
if (resp && resp.match(/^y(es)?$/i))
dactyl.open(urls, params, true);
});
- params = params || {};
if (isString(params))
params = { where: params };
options.push("private");
let win = window.openDialog(document.documentURI, "_blank", options.join(","));
- util.waitFor(function () win.document.readyState === "complete");
+ util.waitFor(() => win.document.readyState === "complete");
browser = win.dactyl && win.dactyl.modules.config.tabbrowser || win.getBrowser();
// FALLTHROUGH
case dactyl.CURRENT_TAB:
}, this);
},
stringToURLArray: deprecated("dactyl.parseURLs", "parseURLs"),
- urlish: Class.Memoize(function () util.regexp(literal(/*
+ urlish: Class.Memoize(() => util.regexp(literal(/*
^ (
<domain>+ (:\d+)? (/ .*) |
<domain>+ (:\d+) |
* @param {function} func The function to call
* @param {object} self The 'this' object for the function.
*/
- trapErrors: function trapErrors(func, self) {
+ trapErrors: function trapErrors(func, self, ...args) {
try {
if (isString(func))
func = self[func];
- return func.apply(self || this, Array.slice(arguments, 2));
+ return func.apply(self || this, args);
}
catch (e) {
try {
if (error instanceof FailedAssertion && error.noTrace || error.message === "Interrupted") {
let context = contexts.context;
let prefix = context ? context.file + ":" + context.line + ": " : "";
- if (error.message && error.message.indexOf(prefix) !== 0 &&
+ if (error.message && !error.message.startsWith(prefix) &&
prefix != "[Command Line]:1: ")
error.message = prefix + error.message;
return [];
}
},
- wrapCallback: function wrapCallback(callback, self) {
- self = self || this;
+ wrapCallback: function wrapCallback(callback, self=this) {
let save = ["forceOpen"];
- let saved = save.map(function (p) dactyl[p]);
+ let saved = save.map(p => dactyl[p]);
return function wrappedCallback() {
let args = arguments;
return dactyl.withSavedValues(save, function () {
- saved.forEach(function (p, i) dactyl[save[i]] = p);
+ saved.forEach((p, i) => { dactyl[save[i]] = p; });
try {
return callback.apply(self, args);
}
dactyl.reportError(e, true);
}
});
- }
+ };
},
/**
* @property {[Window]} Returns an array of all the host application's
* open windows.
*/
- get windows() [win for (win in iter(services.windowMediator.getEnumerator("navigator:browser"))) if (win.dactyl)],
+ get windows() [w for (w of overlay.windows)]
}, {
- toolbarHidden: function hidden(elem) (elem.getAttribute("autohide") || elem.getAttribute("collapsed")) == "true"
+ toolbarHidden: function toolbarHidden(elem) "true" == (elem.getAttribute("autohide") ||
+ elem.getAttribute("collapsed"))
}, {
cache: function initCache() {
cache.register("help/plugins.xml", function () {
try {
let info = contexts.getDocs(context);
if (DOM.isJSONXML(info)) {
- let langs = info.slice(2).filter(function (e) isArray(e) && isObject(e[1]) && e[1].lang);
+ let langs = info.slice(2)
+ .filter(e => isArray(e) && isObject(e[1]) && e[1].lang);
if (langs) {
- let lang = config.bestLocale(l[1].lang for each (l in langs));
+ let lang = config.bestLocale(langs.map(l => l[1].lang));
info = info.slice(0, 2).concat(
- info.slice(2).filter(function (e) !isArray(e) || !isObject(e[1])
- || e[1].lang == lang));
-
- for each (let elem in info.slice(2).filter(function (e) isArray(e) && e[0] == "info" && isObject(e[1])))
- for (let attr in values(["name", "summary", "href"]))
+ info.slice(2).filter(e => !isArray(e)
+ || !isObject(e[1])
+ || e[1].lang == lang));
+
+ info.slice(2)
+ .filter(e => isArray(e) && e[0] == "info" && isObject(e[1]))
+ .forEach(elem => {
+ for (let attr of ["name", "summary", "href"])
if (attr in elem[1])
info[attr] = elem[1][attr];
+ });
}
body.push(["h2", { xmlns: "dactyl", tag: info[1].name + '-plugin' },
String(info[1].summary)]);
["toc", { start: "2" }],
body]);
- });
+ }, true);
cache.register("help/index.xml", function () {
return '<?xml version="1.0"?>\n' +
DOM.toXML(["overlay", { xmlns: "dactyl" },
- template.map(dactyl.indices, function ([name, iter])
+ template.map(dactyl.indices, ([name, iter]) =>
["dl", { insertafter: name + "-index" },
template.map(iter(), util.identity)],
"\n\n")]);
- });
+ }, true);
cache.register("help/gui.xml", function () {
return '<?xml version="1.0"?>\n' +
DOM.toXML(["overlay", { xmlns: "dactyl" },
["dl", { insertafter: "dialog-list" },
- template.map(config.dialogs, function ([name, val])
+ template.map(config.dialogs, ([name, val]) =>
(!val[2] || val[2]())
? [["dt", {}, name],
["dd", {}, val[0]]]
: undefined,
"\n")]]);
- });
+ }, true);
cache.register("help/privacy.xml", function () {
return '<?xml version="1.0"?>\n' +
DOM.toXML(["overlay", { xmlns: "dactyl" },
["dl", { insertafter: "sanitize-items" },
template.map(options.get("sanitizeitems").values
- .sort(function (a, b) String.localeCompare(a.name,
- b.name)),
- function ({ name, description })
+ .sort((a, b) => String.localeCompare(a.name,
+ b.name)),
+ ({ name, description }) =>
[["dt", {}, name],
["dd", {}, template.linkifyHelp(description, true)]],
"\n")]]);
- });
+ }, true);
},
events: function initEvents() {
events.listen(window, dactyl, "events", true);
M: ["Always show messages outside of the status line"]
},
setter: function (opts) {
- if (loaded.commandline || ~opts.indexOf("c"))
+ if (loaded.has("commandline") || ~opts.indexOf("c"))
commandline.widgets.updateVisibility();
}
},
}, config.guioptions),
setter: function (opts) {
for (let [opt, [, ids]] in Iterator(this.opts)) {
- ids.map(function (id) document.getElementById(id))
+ ids.map(id => document.getElementById(id))
.forEach(function (elem) {
if (elem)
dactyl.setNodeVisible(elem, opts.indexOf(opt) >= 0);
},
setter: function (opts) {
let dir = ["horizontal", "vertical"].filter(
- function (dir) !Array.some(opts,
- function (o) this.opts[o] && this.opts[o][1] == dir, this),
- this);
- let class_ = dir.map(function (dir) "html|html > xul|scrollbar[orient=" + dir + "]");
+ dir => !Array.some(opts,
+ o => this.opts[o] && this.opts[o][1] == dir));
+ let class_ = dir.map(dir => "html|html > xul|scrollbar[orient=" + dir + "]");
styles.system.add("scrollbar", "*",
class_.length ? class_.join(", ") + " { visibility: collapse !important; }" : "",
styles.system.add("taboptions", "chrome://*",
classes.length ? classes.join(",") + "{ display: none; }" : "");
- if (!dactyl.has("Gecko2")) {
- tabs.tabBinding.enabled = Array.some(opts, function (k) k in this.opts, this);
- tabs.updateTabCount();
- }
if (config.tabbrowser.tabContainer._positionPinnedTabs)
config.tabbrowser.tabContainer._positionPinnedTabs();
},
Option.validIf(!/[nN]/.test(opts), "Tab numbering not available in this " + config.host + " version")
*/
}
- ].filter(function (group) !group.feature || dactyl.has(group.feature));
+ ].filter(group => !group.feature || dactyl.has(group.feature));
options.add(["guioptions", "go"],
"Show or hide certain GUI elements like the menu or toolbar",
"rb" + [k for ([k, v] in iter(groups[1].opts))
if (!Dactyl.toolbarHidden(document.getElementById(v[1][0])))].join(""),
- values: array(groups).map(function (g) [[k, v[0]] for ([k, v] in Iterator(g.opts))]).flatten(),
+ values: array(groups).map(g => [[k, v[0]] for ([k, v] in Iterator(g.opts))])
+ .flatten(),
setter: function (value) {
for (let group in values(groups))
events.checkFocus();
return value;
},
- validator: function (val) Option.validateCompleter.call(this, val) &&
- groups.every(function (g) !g.validator || g.validator(val))
+ validator: function (val) Option.validateCompleter.call(this, val)
+ && groups.every(g => !g.validator || g.validator(val))
});
- options.add(["helpfile", "hf"],
- "Name of the main help file",
- "string", "intro");
-
options.add(["loadplugins", "lpl"],
"A regexp list that defines which plugins are loaded at startup and via :loadplugins",
"regexplist", "'\\.(js|" + config.fileExtension + ")$'");
options.add(["verbose", "vbs"],
"Define which info messages are displayed",
"number", 1,
- { validator: function (value) Option.validIf(value >= 0 && value <= 15, "Value must be between 0 and 15") });
+ { validator: function (value) Option.validIf(value >= 0 && value <= 15,
+ "Value must be between 0 and 15") });
options.add(["visualbell", "vb"],
"Use visual bell instead of beeping on errors",
let arg = args[0] || "";
let items = dactyl.getMenuItems(arg);
- dactyl.assert(items.some(function (i) i.dactylPath == arg),
+ dactyl.assert(items.some(i => i.dactylPath == arg),
_("emenu.notFound", arg));
for (let [, item] in Iterator(items)) {
if (args["+purgecaches"])
cache.flush();
- util.delay(function () { util.rehash(args) });
+ util.delay(() => { util.rehash(args) });
},
{
argCount: "0", // FIXME
};
toolbarCommand(["toolbars[how]", "tbs[how]"], "Show the named toolbar",
- function (toolbar) dactyl.setNodeVisible(toolbar, true),
- function ({ item }) Dactyl.toolbarHidden(item));
+ toolbar => dactyl.setNodeVisible(toolbar, true),
+ ({ item }) => Dactyl.toolbarHidden(item));
toolbarCommand(["toolbarh[ide]", "tbh[ide]"], "Hide the named toolbar",
- function (toolbar) dactyl.setNodeVisible(toolbar, false),
- function ({ item }) !Dactyl.toolbarHidden(item));
+ toolbar => dactyl.setNodeVisible(toolbar, false),
+ ({ item }) => !Dactyl.toolbarHidden(item));
toolbarCommand(["toolbart[oggle]", "tbt[oggle]"], "Toggle the named toolbar",
- function (toolbar) dactyl.setNodeVisible(toolbar, Dactyl.toolbarHidden(toolbar)));
+ toolbar => dactyl.setNodeVisible(toolbar, Dactyl.toolbarHidden(toolbar)));
}
commands.add(["time"],
args = args[0] || "";
if (args[0] == ":")
- var func = function () commands.execute(args, null, false);
+ var func = () => commands.execute(args, null, false);
else
func = dactyl.userFunc(args);
commandline.commandOutput([
["div", {}, [config.appName, " ", config.version, date, " running on: "].join("")],
["div", {}, [window.navigator.userAgent].join("")]
- ])
+ ]);
}
}, {
argCount: "0",
completion: function initCompletion() {
completion.dialog = function dialog(context) {
context.title = ["Dialog"];
- context.filters.push(function ({ item }) !item[2] || item[2]());
+ context.filters.push(({ item }) => !item[2] || item[2]());
context.completions = [[k, v[0], v[2]] for ([k, v] in Iterator(config.dialogs))];
};
description: function (item) item.getAttribute("label"),
highlight: function (item) item.disabled ? "Disabled" : ""
};
- context.generate = function () dactyl.menuItems;
+ context.generate = () => dactyl.menuItems;
};
var toolbox = document.getElementById("navigator-toolbox");
completion.window = function window(context) {
context.title = ["Window", "Title"];
- context.keys = { text: function (win) dactyl.windows.indexOf(win) + 1, description: function (win) win.document.title };
+ context.keys = { text: win => dactyl.windows.indexOf(win) + 1,
+ description: win => win.document.title };
context.completions = dactyl.windows;
};
},
&& root._lightweightTheme._lastScreenWidth == null) {
dactyl.withSavedValues.call(PrivateBrowsingUtils,
- ["isWindowPrivate"], function () {
- PrivateBrowsingUtils.isWindowPrivate = function () false;
-
+ ["isWindowPrivate"], function () {
+ PrivateBrowsingUtils.isWindowPrivate = () => false;
Cu.import("resource://gre/modules/LightweightThemeConsumer.jsm", {})
.LightweightThemeConsumer.call(root._lightweightTheme, document);
});
}
+ if (config.has("default-theme") && "CustomizableUI" in window)
+ overlay.overlayWindow(window, {
+ append: [
+ ["window", { id: document.documentElement.id, "dactyl-australis": "true", xmlns: "xul" }]]
+ });
+
dactyl.timeout(function () {
try {
var args = config.prefs.get("commandline-args")
// dactyl.hideGUI();
if (dactyl.userEval("typeof document", null, "test.js") === "undefined")
- jsmodules.__proto__ = XPCSafeJSObjectWrapper(window);
+ jsmodules.__proto__ = window;
if (dactyl.commandLineOptions.preCommands)
dactyl.commandLineOptions.preCommands.forEach(function (cmd) {
}
});
-// vim: set fdm=marker sw=4 ts=4 et:
+// vim: set fdm=marker sw=4 sts=4 ts=8 et: