diff --git a/common/content/commands.js b/common/content/commands.js index f79584c7..c508757d 100644 --- a/common/content/commands.js +++ b/common/content/commands.js @@ -80,7 +80,7 @@ update(CommandOption, { * E.g. "foo,bar" * @final */ - LIST: ArgType("list", function (arg) arg && arg.split(/\s*,\s*/)) + LIST: ArgType("list", function (arg, quoted) Option.splitList(quoted)) }); /** @@ -748,7 +748,10 @@ const Commands = Module("commands", { */ parseArgs: function (str, params) { try { - function getNextArg(str) { + function getNextArg(str, _keepQuotes) { + if (arguments.length < 2) + _keepQuotes = keepQuotes; + if (str.substr(0, 2) === "<<" && hereDoc) { let arg = /^<<(\S*)/.exec(str)[1]; let count = arg.length + 2; @@ -756,7 +759,7 @@ const Commands = Module("commands", { return [count, "", ""]; return [count, io.readHeredoc(arg), ""]; } - let [count, arg, quote] = Commands.parseArg(str, null, keepQuotes); + let [count, arg, quote] = Commands.parseArg(str, null, _keepQuotes); if (quote == "\\" && !complete) return [, , , "Trailing \\"]; if (quote && !complete) @@ -782,7 +785,7 @@ const Commands = Module("commands", { var invalid = false; // FIXME: best way to specify these requirements? var onlyArgumentsRemaining = allowUnknownOptions || options.length == 0; // after a -- has been found - var arg = null; + var arg = null, quoted = null; var count = 0; // the length of the argument var i = 0; var completeOpts; @@ -845,12 +848,14 @@ const Commands = Module("commands", { for (let [, optname] in Iterator(opt.names)) { if (sub.indexOf(optname) == 0) { invalid = false; + quoted = null; arg = null; quote = null; count = 0; let sep = sub[optname.length]; if (sep == "=" || /\s/.test(sep) && opt.type != CommandOption.NOARG) { - [count, arg, quote, error] = getNextArg(sub.substr(optname.length + 1)); + [count, quoted, quote, error] = getNextArg(sub.substr(optname.length + 1), true); + arg = Option.dequote(quoted); dactyl.assert(!error, error); // if we add the argument to an option after a space, it MUST not be empty @@ -879,7 +884,7 @@ const Commands = Module("commands", { if (!complete || arg != null) { if (opt.type) { let orig = arg; - arg = opt.type.parse(arg); + arg = opt.type.parse(arg, quoted); if (complete && isArray(arg)) { args.completeFilter = arg[arg.length - 1]; @@ -896,7 +901,7 @@ const Commands = Module("commands", { // we have a validator function if (typeof opt.validator == "function") { - if (opt.validator.call(this, arg) == false) { + if (opt.validator.call(this, arg, quoted) == false) { fail("Invalid argument for option: " + optname); if (complete) // Always true. complete.highlight(args.completeStart, count - 1, "SPELLCHECK"); @@ -904,11 +909,12 @@ const Commands = Module("commands", { } } - // option allowed multiple times - if (opt.multiple) - args[opt.names[0]] = (args[opt.names[0]] || []).concat(arg); - else - args[opt.names[0]] = opt.type == CommandOption.NOARG || arg; + if (arg != null || opt.type == CommandOption.NOARG) + // option allowed multiple times + if (opt.multiple) + args[opt.names[0]] = (args[opt.names[0]] || []).concat(arg); + else + args[opt.names[0]] = opt.type == CommandOption.NOARG || arg; i += optname.length + count; if (i == str.length) diff --git a/common/content/io.js b/common/content/io.js index 5cd87618..29731ead 100644 --- a/common/content/io.js +++ b/common/content/io.js @@ -13,20 +13,21 @@ plugins.contexts = {}; function Script(file) { let self = set.has(plugins, file.path) && plugins[file.path]; if (self) { - if (self.onUnload) + if (set.has(self, "onUnload")) self.onUnload(); } else { - self = { __proto__: plugins }; - plugins[file.path] = self; - self.NAME = file.leafName.replace(/\..*/, "").replace(/-([a-z])/g, function (m, n1) n1.toUpperCase()); - self.PATH = file.path; - self.CONTEXT = self; + self = update({ __proto__: plugins }, { + NAME: file.leafName.replace(/\..*/, "").replace(/-([a-z])/g, function (m, n1) n1.toUpperCase()), + PATH: file.path, + CONTEXT: self + }); + Class.replaceProperty(plugins, file.path, self); // This belongs elsewhere if (io.getRuntimeDirectories("plugins").some( function (dir) dir.contains(file, false))) - plugins[self.NAME] = self; + Class.replaceProperty(plugins, self.NAME, self); } plugins.contexts[file.path] = self; return self; @@ -67,6 +68,13 @@ const IO = Module("io", { services.downloadManager.addListener(this.downloadListener); }, + destroy: function () { + services.downloadManager.removeListener(this.downloadListener); + for (let [, plugin] in Iterator(plugins.contexts)) + if (plugin.onUnload) + plugin.onUnload(); + }, + // TODO: there seems to be no way, short of a new component, to change // the process's CWD - see https://bugzilla.mozilla.org/show_bug.cgi?id=280953 /** @@ -111,13 +119,6 @@ const IO = Module("io", { return this.cwd; }, - destroy: function () { - services.downloadManager.removeListener(this.downloadListener); - for (let [, plugin] in Iterator(plugins.contexts)) - if (plugin.onUnload) - plugin.onUnload(); - }, - /** * @property {function} File class. * @final diff --git a/common/modules/overlay.jsm b/common/modules/overlay.jsm index 15e9d73e..c7217174 100644 --- a/common/modules/overlay.jsm +++ b/common/modules/overlay.jsm @@ -7,7 +7,7 @@ Components.utils.import("resource://dactyl/base.jsm"); defineModule("overlay", { exports: ["ModuleBase"], - require: ["sanitizer", "services", "template", "util"], + require: ["highlight", "sanitizer", "services", "template", "util"], }); /** diff --git a/common/modules/util.jsm b/common/modules/util.jsm index 4acf60b7..6d5f0ff1 100644 --- a/common/modules/util.jsm +++ b/common/modules/util.jsm @@ -932,11 +932,13 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]) }, "dactyl-rehash": function () { util.dump("dactyl: util: observe: dactyl-rehash"); - for (let module in values(defineModule.modules)) + for (let module in values(defineModule.modules)) { + util.dump("dactyl: util: init(" + module + ")"); if (module.reinit) module.reinit(); else module.init(); + } }, "toplevel-window-ready": function (window, data) { window.addEventListener("DOMContentLoaded", wrapCallback(function listener(event) {