XML.ignoreWhitespace = false;
XML.prettyPrinting = false;
-var userContext = { __proto__: modules };
-var _userContext = newContext(userContext);
-
var EVAL_ERROR = "__dactyl_eval_error";
var EVAL_RESULT = "__dactyl_eval_result";
var EVAL_STRING = "__dactyl_eval_string";
};
styles.registerSheet("resource://dactyl-skin/dactyl.css");
+
+ this.cleanups = [];
+ this.cleanups.push(util.overlayObject(window, {
+ focusAndSelectUrlBar: function focusAndSelectUrlBar() {
+ switch (options.get("strictfocus").getKey(document.documentURIObject || util.newURI(document.documentURI), "moderate")) {
+ case "laissez-faire":
+ if (!Events.isHidden(window.gURLBar, true))
+ return focusAndSelectUrlBar.superapply(this, arguments);
+ default:
+ // Evil. Ignore.
+ }
+ }
+ }));
},
cleanup: function () {
+ for (let cleanup in values(this.cleanups))
+ cleanup.call(this);
+
delete window.dactyl;
delete window.liberator;
autocommands.trigger("Leave", {});
},
+ // initially hide all GUI elements, they are later restored unless the user
+ // has :set go= or something similar in his config
+ hideGUI: function () {
+ let guioptions = config.guioptions;
+ for (let option in guioptions) {
+ guioptions[option].forEach(function (elem) {
+ try {
+ document.getElementById(elem).collapsed = true;
+ }
+ catch (e) {}
+ });
+ }
+ },
+
+
observers: {
- "dactyl-cleanup": function dactyl_cleanup() {
+ "dactyl-cleanup": function dactyl_cleanup(subject, reason) {
let modules = dactyl.modules;
for (let mod in values(modules.moduleList.reverse())) {
mod.stale = true;
if ("cleanup" in mod)
- this.trapErrors("cleanup", mod);
+ this.trapErrors("cleanup", mod, reason);
if ("destroy" in mod)
- this.trapErrors("destroy", mod);
+ this.trapErrors("destroy", mod, reason);
}
for (let mod in values(modules.ownPropertyValues.reverse()))
if (mod instanceof Class && "INIT" in mod && "cleanup" in mod.INIT)
- this.trapErrors(mod.cleanup, mod, dactyl, modules, window);
+ this.trapErrors(mod.cleanup, mod, dactyl, modules, window, reason);
for (let name in values(Object.getOwnPropertyNames(modules).reverse()))
try {
}),
/**
- * @property {number} The current main mode.
+ * @property {Modes.Mode} The current main mode.
* @see modes#mainModes
*/
mode: deprecated("modes.main", {
set: function mode(val) modes.main = val
}),
- get menuItems() Dactyl.getMenuItems(),
+ get menuItems() {
+ function dispatch(node, name) {
+ let event = node.ownerDocument.createEvent("Events");
+ event.initEvent(name, false, false);
+ node.dispatchEvent(event);
+ }
+
+ function addChildren(node, parent) {
+ if (~["menu", "menupopup"].indexOf(node.localName) && node.children.length)
+ dispatch(node, "popupshowing");
+
+ for (let [, item] in Iterator(node.childNodes)) {
+ if (item.childNodes.length == 0 && item.localName == "menuitem"
+ && !item.hidden
+ && !/rdf:http:/.test(item.getAttribute("label"))) { // FIXME
+ item.dactylPath = parent + item.getAttribute("label");
+ items.push(item);
+ }
+ else {
+ let path = parent;
+ if (item.localName == "menu")
+ path += item.getAttribute("label") + ".";
+ addChildren(item, path);
+ }
+ }
+ }
+
+ let items = [];
+ addChildren(document.getElementById(config.guioptions["m"][1]), "");
+ return items;
+ },
// Global constants
CURRENT_TAB: "here",
},
addUsageCommand: function (params) {
+ function keys(item) (item.names || [item.name]).concat(item.description, item.columns || []);
+
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));
- let filters = args.map(function (arg) RegExp("\\b" + util.regexp.escape(arg) + "\\b", "i"));
+ let filters = args.map(function (arg) util.regexp("\\b" + util.regexp.escape(arg) + "\\b", "i"));
if (filters.length)
- results = results.filter(function (item) filters.every(function (re) re.test(item.name + " " + item.description)));
+ results = results.filter(function (item) filters.every(function (re) keys(item).some(re.closure.test)));
commandline.commandOutput(
template.usage(results, params.format));
argCount: "*",
completer: function (context, args) {
context.keys.text = util.identity;
- context.keys.description = function () seen[this.text] + " matching items";
+ context.keys.description = function () seen[this.text] + /*L*/" matching items";
let seen = {};
- context.completions = array(item.description.toLowerCase().split(/[()\s]+/)
+ context.completions = array(keys(item).join(" ").toLowerCase().split(/[()\s]+/)
for (item in params.iterate(args)))
.flatten().filter(function (w) /^\w[\w-_']+$/.test(w))
.map(function (k) {
let tags = services["dactyl:"].HELP_TAGS;
for (let obj in values(results)) {
let res = dactyl.generateHelp(obj, null, null, true);
- if (!set.has(tags, obj.helpTag))
+ if (!Set.has(tags, obj.helpTag))
res[1].@tag = obj.helpTag;
yield res;
clipboardHelper.copyString(str);
if (verbose) {
- let message = { message: "Yanked " + str };
+ let message = { message: _("dactyl.yank", str) };
try {
message.domains = [util.newURI(str).host];
}
echoerr: function echoerr(str, flags) {
flags |= commandline.APPEND_TO_MESSAGES;
- if (isinstance(str, ["Error", "Exception"]))
+ if (isinstance(str, ["DOMException", "Error", "Exception"]) || isinstance(str, ["XPCWrappedNative_NoHelper"]) && /^\[Exception/.test(str))
dactyl.reportError(str);
if (isObject(str) && "echoerr" in str)
str = str.echoerr;
({ file: fileName, line: lineNumber, context: ctxt }) = info;
if (!context && fileName && fileName[0] !== "[")
- context = _userContext || ctxt;
+ context = ctxt || _userContext;
if (isinstance(context, ["Sandbox"]))
return Cu.evalInSandbox(str, context, "1.8", fileName, lineNumber);
* @param {string} feature The feature name.
* @returns {boolean}
*/
- has: function (feature) set.has(config.features, feature),
+ has: function (feature) Set.has(config.features, feature),
/**
* Returns the URL of the specified help *topic* if it exists.
* Initialize the help system.
*/
initHelp: function (force) {
+ // Waits for the add-on to become available, if necessary.
+ config.addon;
+ config.version;
+
if (force || !this.helpInitialized) {
if ("noscriptOverlay" in window) {
noscriptOverlay.safeAllow("chrome-data:", true, false);
let body = XML();
for (let [, context] in Iterator(plugins.contexts))
- if (context && context.INFO instanceof XML) {
- let info = context.INFO;
- if (info.*.@lang.length()) {
- let lang = config.bestLocale(String(a) for each (a in info.*.@lang));
+ try {
+ let info = contexts.getDocs(context);
+ if (info instanceof XML) {
+ if (info.*.@lang.length()) {
+ let lang = config.bestLocale(String(a) for each (a in info.*.@lang));
- info.* = info.*.(function::attribute("lang").length() == 0 || @lang == lang);
+ info.* = info.*.(function::attribute("lang").length() == 0 || @lang == lang);
- for each (let elem in info.NS::info)
- for each (let attr in ["@name", "@summary", "@href"])
- if (elem[attr].length())
- info[attr] = elem[attr];
+ for each (let elem in info.NS::info)
+ for each (let attr in ["@name", "@summary", "@href"])
+ if (elem[attr].length())
+ info[attr] = elem[attr];
+ }
+ body += <h2 xmlns={NS.uri} tag={info.@name + '-plugin'}>{info.@summary}</h2> +
+ info;
}
- body += <h2 xmlns={NS.uri} tag={context.INFO.@name + '-plugin'}>{context.INFO.@summary}</h2> +
- context.INFO;
+ }
+ catch (e) {
+ util.reportError(e);
}
let help =
'<?xml version="1.0"?>\n' +
'<?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>\n' +
'<!DOCTYPE document SYSTEM "resource://dactyl-content/dactyl.dtd">\n' +
- unescape(encodeURI( // UTF-8 handling hack.
<document xmlns={NS}
name="plugins" title={config.appName + " Plugins"}>
- <h1 tag="using-plugins">Using Plugins</h1>
+ <h1 tag="using-plugins">{_("help.title.Using Plugins")}</h1>
<toc start="2"/>
{body}
- </document>.toXMLString()));
+ </document>.toXMLString();
fileMap["plugins"] = function () ['text/xml;charset=UTF-8', help];
fileMap["versions"] = function () {
default xml namespace = NS;
function rec(text, level, li) {
+ XML.ignoreWhitespace = XML.prettyPrinting = false;
+
let res = <></>;
let list, space, i = 0;
if (!list)
res += list = <ul/>;
let li = <li/>;
- li.* += rec(match.content.replace(RegExp("^" + match.space, "gm"), ""), level + 1, li)
+ li.* += rec(match.content.replace(RegExp("^" + match.space, "gm"), ""), level + 1, li);
list.* += li;
}
else if (match.par) {
}
list = null;
- if (level == 0 && /^.*:\n$/.test(match.par))
- res += <h2>{template.linkifyHelp(par.slice(0, -1), true)}</h2>;
+ if (level == 0 && /^.*:\n$/.test(match.par)) {
+ let text = par.slice(0, -1);
+ res += <h2 tag={"news-" + text}>{template.linkifyHelp(text, true)}</h2>;
+ }
else {
let [, a, b] = /^(IMPORTANT:?)?([^]*)/.exec(par);
res += <p highlight={group + " HelpNews"}>{
return res;
}
+ XML.ignoreWhitespace = XML.prettyPrinting = false;
let body = rec(NEWS, 0);
for each (let li in body..li) {
let list = li..li.(@NS::highlight == "HelpNewsOld");
}
}
- XML.prettyPrinting = XML.ignoreWhitespace = false;
return ["application/xml",
'<?xml version="1.0"?>\n' +
'<?xml-stylesheet type="text/xsl" href="dactyl://content/help.xsl"?>\n' +
'<!DOCTYPE document SYSTEM "resource://dactyl-content/dactyl.dtd">\n' +
- unescape(encodeURI( // UTF-8 handling hack.
<document xmlns={NS} xmlns:dactyl={NS}
name="versions" title={config.appName + " Versions"}>
<h1 tag="versions news NEWS">{config.appName} Versions</h1>
<toc start="2"/>
{body}
- </document>.toXMLString()))
+ </document>.toXMLString()
];
}
addTags("versions", util.httpGet("dactyl://help/versions").responseXML);
overlayMap["index"] = ['text/xml;charset=UTF-8',
'<?xml version="1.0"?>\n' +
- '<overlay xmlns="' + NS + '">\n' +
- unescape(encodeURI( // UTF-8 handling hack.
+ <overlay xmlns={NS}>{
template.map(dactyl.indices, function ([name, iter])
<dl insertafter={name + "-index"}>{
template.map(iter(), util.identity)
- }</dl>, <>{"\n\n"}</>))) +
- '\n</overlay>'];
-
+ }</dl>, <>{"\n\n"}</>)
+ }</overlay>];
addTags("index", util.httpGet("dactyl://help-overlay/index").responseXML);
+ overlayMap["gui"] = ['text/xml;charset=UTF-8',
+ '<?xml version="1.0"?>\n' +
+ <overlay xmlns={NS}>
+ <dl insertafter="dialog-list">{
+ template.map(config.dialogs, function ([name, val])
+ (!val[2] || val[2]())
+ ? <><dt>{name}</dt><dd>{val[0]}</dd></>
+ : undefined,
+ <>{"\n"}</>)
+ }</dl>
+ </overlay>];
+
+
this.helpInitialized = true;
}
},
addURIEntry(file, "data:text/plain;charset=UTF-8," + encodeURI(data));
}
- let empty = set("area base basefont br col frame hr img input isindex link meta param"
+ let empty = Set("area base basefont br col frame hr img input isindex link meta param"
.split(" "));
function fix(node) {
switch(node.nodeType) {
- case Node.ELEMENT_NODE:
- if (isinstance(node, [HTMLBaseElement]))
- return;
-
- data.push("<"); data.push(node.localName);
- if (node instanceof HTMLHtmlElement)
- data.push(" xmlns=" + XHTML.uri.quote());
-
- for (let { name, value } in array.iterValues(node.attributes)) {
- if (name == "dactyl:highlight") {
- set.add(styles, value);
- name = "class";
- value = "hl-" + value;
- }
- if (name == "href") {
- value = node.href;
- if (value.indexOf("dactyl://help-tag/") == 0) {
- let uri = services.io.newChannel(value, null, null).originalURI;
- value = uri.spec == value ? "javascript:;" : uri.path.substr(1);
- }
- if (!/^#|[\/](#|$)|^[a-z]+:/.test(value))
- value = value.replace(/(#|$)/, ".xhtml$1");
- }
- if (name == "src" && value.indexOf(":") > 0) {
- chromeFiles[value] = value.replace(/.*\//, "");
- value = value.replace(/.*\//, "");
+ case Node.ELEMENT_NODE:
+ if (isinstance(node, [HTMLBaseElement]))
+ return;
+
+ data.push("<"); data.push(node.localName);
+ if (node instanceof HTMLHtmlElement)
+ data.push(" xmlns=" + XHTML.uri.quote(),
+ " xmlns:dactyl=" + NS.uri.quote());
+
+ for (let { name, value } in array.iterValues(node.attributes)) {
+ if (name == "dactyl:highlight") {
+ Set.add(styles, value);
+ name = "class";
+ value = "hl-" + value;
+ }
+ if (name == "href") {
+ value = node.href || value;
+ if (value.indexOf("dactyl://help-tag/") == 0) {
+ let uri = services.io.newChannel(value, null, null).originalURI;
+ value = uri.spec == value ? "javascript:;" : uri.path.substr(1);
}
- data.push(" ");
- data.push(name);
- data.push('="');
- data.push(<>{value}</>.toXMLString());
- data.push('"');
+ if (!/^#|[\/](#|$)|^[a-z]+:/.test(value))
+ value = value.replace(/(#|$)/, ".xhtml$1");
}
- if (node.localName in empty)
- data.push(" />");
- else {
- data.push(">");
- if (node instanceof HTMLHeadElement)
- data.push(<link rel="stylesheet" type="text/css" href="help.css"/>.toXMLString());
- Array.map(node.childNodes, fix);
- data.push("</"); data.push(node.localName); data.push(">");
+ if (name == "src" && value.indexOf(":") > 0) {
+ chromeFiles[value] = value.replace(/.*\//, "");
+ value = value.replace(/.*\//, "");
}
- break;
- case Node.TEXT_NODE:
- data.push(<>{node.textContent}</>.toXMLString());
+
+ data.push(" ", name, '="',
+ <>{value}</>.toXMLString().replace(/"/g, """),
+ '"');
+ }
+ if (node.localName in empty)
+ data.push(" />");
+ else {
+ data.push(">");
+ if (node instanceof HTMLHeadElement)
+ data.push(<link rel="stylesheet" type="text/css" href="help.css"/>.toXMLString());
+ Array.map(node.childNodes, fix);
+ data.push("</", node.localName, ">");
+ }
+ break;
+ case Node.TEXT_NODE:
+ data.push(<>{node.textContent}</>.toXMLString());
}
}
let chromeFiles = {};
let styles = {};
for (let [file, ] in Iterator(services["dactyl:"].FILE_MAP)) {
- dactyl.open("dactyl://help/" + file);
- dactyl.modules.events.waitForPageLoad();
- let data = [
+ let url = "dactyl://help/" + file;
+ dactyl.open(url);
+ util.waitFor(function () content.location.href == url && buffer.loaded
+ && content.document.documentElement instanceof HTMLHtmlElement,
+ 15000);
+ events.waitForPageLoad();
+ var data = [
'<?xml version="1.0" encoding="UTF-8"?>\n',
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\n',
' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n'
addDataEntry(file + ".xhtml", data.join(""));
}
- let data = [h for (h in highlight) if (set.has(styles, h.class) || /^Help/.test(h.class))]
+ let data = [h for (h in highlight) if (Set.has(styles, h.class) || /^Help/.test(h.class))]
.map(function (h) h.selector
.replace(/^\[.*?=(.*?)\]/, ".hl-$1")
.replace(/html\|/g, "") + "\t" + "{" + h.cssText + "}")
if (obj instanceof Command) {
link = function (cmd) <ex>{cmd}</ex>;
args = obj.parseArgs("", CompletionContext(str || ""));
- spec = function (cmd) cmd + (obj.bang ? <oa>!</oa> : <></>);
+ spec = function (cmd) <>{
+ obj.count ? <oa>count</oa> : <></>
+ }{
+ cmd
+ }{
+ obj.bang ? <oa>!</oa> : <></>
+ }</>;
}
else if (obj instanceof Map) {
spec = function (map) obj.count ? <><oa>count</oa>{map}</> : <>{map}</>;
};
}
else if (obj instanceof Option) {
+ tag = spec = function (name) <>'{name}'</>;
link = function (opt, name) <o>{name}</o>;
+ args = { value: "", values: [] };
}
XML.prettyPrinting = false;
<description>{
obj.description ? br + <p>{template.linkifyHelp(obj.description.replace(/\.?$/, "."), true)}</p> : "" }{
extraHelp ? br + extraHelp : "" }{
- !(extraHelp || obj.description) ? br + <p>Sorry, no help available.</p> : "" }
+ !(extraHelp || obj.description) ? br + <p><!--L-->Sorry, no help available.</p> : "" }
</description>
</item></>;
}
if (obj.completer)
- add(completion._runCompleter(obj.completer, "", null, args).items
+ add(completion._runCompleter(obj.closure.completer, "", null, args).items
.map(function (i) [i.text, i.description]));
if (obj.options && obj.options.some(function (o) o.description))
* These are set and accessed with the "g:" prefix.
*/
_globalVariables: {},
- globalVariables: deprecated("the options system", {
+ globalVariables: deprecated(_("deprecated.for.theOptionsSystem"), {
get: function globalVariables() this._globalVariables
}),
let loadplugins = options.get("loadplugins");
if (args)
- loadplugins = { __proto__: loadplugins, value: args.map(Option.parseRegexp) }
+ loadplugins = { __proto__: loadplugins, value: args.map(Option.parseRegexp) };
dir.readDirectory(true).forEach(function (file) {
- if (file.isFile() && loadplugins.getKey(file.path) && !(!force && file.path in dactyl.pluginFiles)) {
+ if (file.isFile() && loadplugins.getKey(file.path)
+ && !(!force && file.path in dactyl.pluginFiles && dactyl.pluginFiles[file.path] >= file.lastModifiedTime)) {
try {
io.source(file.path);
- dactyl.pluginFiles[file.path] = true;
+ dactyl.pluginFiles[file.path] = file.lastModifiedTime;
}
catch (e) {
dactyl.reportError(e);
onExecute: function onExecute(event) {
let cmd = event.originalTarget.getAttribute("dactyl-execute");
commands.execute(cmd, null, false, null,
- { file: "[Command Line]", line: 1 });
+ { file: /*L*/"[Command Line]", line: 1 });
},
/**
urls = dactyl.parseURLs(urls);
if (urls.length > prefs.get("browser.tabs.maxOpenBeforeWarn", 20) && !force)
- return commandline.input("This will open " + urls.length + " new tabs. Would you like to continue? (yes/[no]) ",
+ return commandline.input(_("dactyl.prompt.openMany", urls.length) + " ",
function (resp) {
if (resp && resp.match(/^y(es)?$/i))
dactyl.open(urls, params, true);
* ['www.google.com/search?q=bla', 'www.osnews.com']
*
* @param {string} str
- * @returns {string[]}
+ * @returns {[string]}
*/
parseURLs: function parseURLs(str) {
let urls;
return urls.map(function (url) {
url = url.trim();
- if (/^(\.{0,2}|~)(\/|$)/.test(url)) {
+ if (/^(\.{0,2}|~)(\/|$)/.test(url) || util.OS.isWindows && /^[a-z]:/i.test(url)) {
try {
// Try to find a matching file.
let file = io.File(url);
// If it starts with a valid protocol, pass it through.
let proto = /^([-\w]+):/.exec(url);
if (proto && "@mozilla.org/network/protocol;1?name=" + proto[1] in Cc)
- return url.replace(/\s+/g, "");
+ return url;
// Check for a matching search keyword.
let searchURL = this.has("bookmarks") && bookmarks.getSearchURL(url, false);
},
/**
- * @property {Window[]} Returns an array of all the host application's
+ * @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")))],
+ get windows() [win for (win in iter(services.windowMediator.getEnumerator("navigator:browser"))) if (win.dactyl)],
}, {
- // initially hide all GUI elements, they are later restored unless the user
- // has :set go= or something similar in his config
- hideGUI: function () {
- let guioptions = config.guioptions;
- for (let option in guioptions) {
- guioptions[option].forEach(function (elem) {
- try {
- document.getElementById(elem).collapsed = true;
- }
- catch (e) {}
- });
- }
- },
-
- // TODO: move this
- getMenuItems: function () {
- function addChildren(node, parent) {
- for (let [, item] in Iterator(node.childNodes)) {
- if (item.childNodes.length == 0 && item.localName == "menuitem"
- && !/rdf:http:/.test(item.getAttribute("label"))) { // FIXME
- item.fullMenuPath = parent + item.getAttribute("label");
- items.push(item);
- }
- else {
- let path = parent;
- if (item.localName == "menu")
- path += item.getAttribute("label") + ".";
- addChildren(item, path);
- }
- }
- }
-
- let items = [];
- addChildren(document.getElementById(config.guioptions["m"][1]), "");
- return items;
- }
+ toolbarHidden: function hidden(elem) (elem.getAttribute("autohide") || elem.getAttribute("collapsed")) == "true"
}, {
events: function () {
events.listen(window, "click", dactyl.closure.onClick, true);
M: ["Always show messages outside of the status line"]
},
setter: function (opts) {
- if (loaded.commandline)
+ if (loaded.commandline || ~opts.indexOf("c"))
commandline.widgets.updateVisibility();
}
},
true);
prefs.safeSet("layout.scrollbar.side", opts.indexOf("l") >= 0 ? 3 : 2,
- "See 'guioptions' scrollbar flags.");
+ _("option.guioptions.safeSet"));
},
validator: function (opts) Option.validIf(!(opts.indexOf("l") >= 0 && opts.indexOf("r") >= 0),
UTF8("Only one of ‘l’ or ‘r’ allowed"))
// FIXME: cleanup
cleanupValue: config.cleanups.guioptions ||
"r" + [k for ([k, v] in iter(groups[1].opts))
- if (!document.getElementById(v[1][0]).collapsed)].join(""),
+ 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(),
options.add(["urlseparator", "urlsep", "us"],
"The regular expression used to separate multiple URLs in :open and friends",
- "string", "\\|",
+ "string", " \\| ",
{ validator: function (value) RegExp(value) });
options.add(["verbose", "vbs"],
{
setter: function (value) {
prefs.safeSet("accessibility.typeaheadfind.enablesound", !value,
- "See 'visualbell' option");
+ _("option.visualbell.safeSet"));
return value;
}
});
},
mappings: function () {
- mappings.add([modes.MAIN], ["<F1>"],
+ mappings.add([modes.MAIN], ["<open-help>", "<F1>"],
"Open the introductory help page",
function () { dactyl.help(); });
- mappings.add([modes.MAIN], ["<A-F1>"],
+ mappings.add([modes.MAIN], ["<open-single-help>", "<A-F1>"],
"Open the single, consolidated help page",
function () { ex.helpall(); });
}
}, {
argCount: "1",
- bang: true,
completer: function (context) {
context.ignoreCase = true;
completion.dialog(context);
"Execute the specified menu item from the command line",
function (args) {
let arg = args[0] || "";
- let items = Dactyl.getMenuItems();
+ let items = dactyl.menuItems;
- dactyl.assert(items.some(function (i) i.fullMenuPath == arg),
+ dactyl.assert(items.some(function (i) i.dactylPath == arg),
_("emenu.notFound", arg));
for (let [, item] in Iterator(items)) {
- if (item.fullMenuPath == arg)
+ if (item.dactylPath == arg) {
+ dactyl.assert(!item.disabled, _("error.disabled", item.dactylPath));
item.doCommand();
+ }
}
}, {
argCount: "1",
});
commands.add(["loadplugins", "lpl"],
- "Load all plugins immediately",
+ "Load all or matching plugins",
function (args) {
dactyl.loadPlugins(args.length ? args : null, args.bang);
},
bang: true,
keepQuotes: true,
serialGroup: 10,
- serialize: function () [
+ serialize: function () [
{
command: this.name,
literalArg: options["loadplugins"].join(" ")
literal: 0
});
+ commands.add(["exit", "x"],
+ "Quit " + config.appName,
+ function (args) {
+ dactyl.quit(false, args.bang);
+ }, {
+ argCount: "0",
+ bang: true
+ });
+
commands.add(["q[uit]"],
dactyl.has("tabs") ? "Quit current tab" : "Quit application",
function (args) {
"Reload the " + config.appName + " add-on",
function (args) {
if (args.trailing)
- JSMLoader.rehashCmd = args.trailing; // Hack.
+ storage.session.rehashCmd = args.trailing; // Hack.
args.break = true;
util.rehash(args);
},
{
- argCount: "0",
+ argCount: "0", // FIXME
options: [
{
names: ["+u"],
commands.add(["res[tart]"],
"Force " + config.appName + " to restart",
- function () { dactyl.restart(); });
+ function () { dactyl.restart(); },
+ { argCount: "0" });
function findToolbar(name) util.evaluateXPath(
- "//*[@toolbarname=" + util.escapeString(name, "'") + "]",
+ "//*[@toolbarname=" + util.escapeString(name, "'") + " or " +
+ "@toolbarname=" + util.escapeString(name.trim(), "'") + "]",
document).snapshotItem(0);
var toolbox = document.getElementById("navigator-toolbox");
if (toolbox) {
- let hidden = function hidden(elem) (elem.getAttribute("autohide") || elem.getAttribute("collapsed")) == "true";
-
let toolbarCommand = function (names, desc, action, filter) {
commands.add(names, desc,
function (args) {
action(toolbar);
events.checkFocus();
}, {
- argcount: "1",
+ argCount: "1",
completer: function (context) {
completion.toolbar(context);
if (filter)
toolbarCommand(["toolbars[how]", "tbs[how]"], "Show the named toolbar",
function (toolbar) dactyl.setNodeVisible(toolbar, true),
- function ({ item }) hidden(item));
+ function ({ item }) Dactyl.toolbarHidden(item));
toolbarCommand(["toolbarh[ide]", "tbh[ide]"], "Hide the named toolbar",
function (toolbar) dactyl.setNodeVisible(toolbar, false),
- function ({ item }) !hidden(item));
+ function ({ item }) !Dactyl.toolbarHidden(item));
toolbarCommand(["toolbart[oggle]", "tbt[oggle]"], "Toggle the named toolbar",
- function (toolbar) dactyl.setNodeVisible(toolbar, hidden(toolbar)));
+ function (toolbar) dactyl.setNodeVisible(toolbar, Dactyl.toolbarHidden(toolbar)));
}
commands.add(["time"],
args = args[0] || "";
if (args[0] == ":")
- var method = function () commands.execute(args, null, true);
+ var func = function () commands.execute(args, null, false);
else
- method = dactyl.userFunc(args);
+ func = dactyl.userFunc(args);
try {
if (count > 1) {
for (let i in util.interruptibleRange(0, count, 500)) {
let now = Date.now();
- method();
+ func();
total += Date.now() - now;
}
commandline.commandOutput(
<table>
<tr highlight="Title" align="left">
- <th colspan="3">Code execution summary</th>
+ <th colspan="3">{_("title.Code execution summary")}</th>
</tr>
- <tr><td>  Executed:</td><td align="right"><span class="times-executed">{count}</span></td><td>times</td></tr>
- <tr><td>  Average time:</td><td align="right"><span class="time-average">{each.toFixed(2)}</span></td><td>{eachUnits}</td></tr>
- <tr><td>  Total time:</td><td align="right"><span class="time-total">{total.toFixed(2)}</span></td><td>{totalUnits}</td></tr>
+ <tr><td>  {_("title.Executed")}:</td><td align="right"><span class="times-executed">{count}</span></td><td><!--L-->times</td></tr>
+ <tr><td>  {_("title.Average time")}:</td><td align="right"><span class="time-average">{each.toFixed(2)}</span></td><td>{eachUnits}</td></tr>
+ <tr><td>  {_("title.Total time")}:</td><td align="right"><span class="time-total">{total.toFixed(2)}</span></td><td>{totalUnits}</td></tr>
</table>);
}
else {
let beforeTime = Date.now();
- method();
+ func();
if (special)
return;
dactyl.echoerr(e);
}
}, {
- argCount: "+",
+ argCount: "1",
bang: true,
completer: function (context) {
if (/^:/.test(context.filter))
vbs.setFrom = setFrom;
}
}, {
- argCount: "+",
+ argCount: "1",
completer: function (context) completion.ex(context),
count: true,
literal: 0,
completion.menuItem = function menuItem(context) {
context.title = ["Menu Path", "Label"];
context.anchored = false;
- context.keys = { text: "fullMenuPath", description: function (item) item.getAttribute("label") };
- context.completions = dactyl.menuItems;
+ context.keys = {
+ text: "dactylPath",
+ description: function (item) item.getAttribute("label"),
+ highlight: function (item) item.disabled ? "Disabled" : ""
+ };
+ context.generate = function () dactyl.menuItems;
};
var toolbox = document.getElementById("navigator-toolbox");
dactyl.timeout(function () {
try {
- var args = JSMLoader.commandlineArgs || services.commandLineHandler.optionValue;
+ var args = storage.session.commandlineArgs || services.commandLineHandler.optionValue;
if (isString(args))
args = dactyl.parseCommandLine(args);
}
// TODO: we should have some class where all this guioptions stuff fits well
- // Dactyl.hideGUI();
+ // dactyl.hideGUI();
if (dactyl.userEval("typeof document", null, "test.js") === "undefined")
jsmodules.__proto__ = XPCSafeJSObjectWrapper(window);
dactyl.execute(cmd);
});
- if (JSMLoader.rehashCmd)
- dactyl.execute(JSMLoader.rehashCmd);
- JSMLoader.rehashCmd = null;
+ if (storage.session.rehashCmd)
+ dactyl.execute(storage.session.rehashCmd);
+ storage.session.rehashCmd = null;
dactyl.fullyInitialized = true;
dactyl.triggerObserver("enter", null);