diff --git a/common/content/commands.js b/common/content/commands.js index 7105105b..4f0be074 100644 --- a/common/content/commands.js +++ b/common/content/commands.js @@ -111,13 +111,13 @@ update(CommandOption, { var Command = Class("Command", { init: function (specs, description, action, extraInfo) { specs = Array.concat(specs); // XXX - let parsedSpecs = Command.parseSpecs(specs); + let parsedSpecs = extraInfo.parsedSpecs || Command.parseSpecs(specs); this.specs = specs; this.shortNames = array.compact(parsedSpecs.map(function (n) n[1])); this.longNames = parsedSpecs.map(function (n) n[0]); this.name = this.longNames[0]; - this.names = array(parsedSpecs).flatten(); + this.names = array.flatten(parsedSpecs); this.description = description; this.action = action; @@ -471,11 +471,15 @@ var Commands = Module("commands", { args[3].definedAt = commands.getCaller(Components.stack.caller.caller); let names = array.flatten(Command.parseSpecs(args[0])); + args.parsedSpecs = names; + dactyl.assert(!names.some(function (name) name in this._exMap && !this._exMap[name].user, this), "E182: Can't replace non-user command: " + args[0][0]); + if (!replace || !args[3].user) dactyl.assert(!names.some(function (name) name in this._exMap, this), "Not replacing command " + args[0]); + for (let name in values(names)) { ex.__defineGetter__(name, function () this._run(name)); if (name in this._exMap) @@ -484,8 +488,10 @@ var Commands = Module("commands", { let name = names[0]; let closure = function () commands._exMap[name]; + memoize(this._exMap, name, function () Command.apply(null, args)); memoize(this._exCommands, this._exCommands.length, closure); + for (let alias in values(names.slice(1))) memoize(this._exMap, alias, closure); diff --git a/common/content/mappings.js b/common/content/mappings.js index f81aaa62..02bd1847 100644 --- a/common/content/mappings.js +++ b/common/content/mappings.js @@ -36,8 +36,7 @@ var Map = Class("Map", { this.id = ++Map.id; this.modes = modes; - this.names = keys.map(events.closure.canonicalKeys); - this.name = this.names[0]; + this._keys = keys; this.action = action; this.description = description; @@ -48,14 +47,17 @@ var Map = Class("Map", { update(this, extraInfo); }, + name: Class.memoize(function () this.names[0]), + + /** @property {string[]} All of this mapping's names (key sequences). */ + names: Class.memoize(function () this._keys.map(events.closure.canonicalKeys)), + get toStringParams() [this.modes.map(function (m) m.name), this.names.map(String.quote)], /** @property {number} A unique ID for this mapping. */ id: null, /** @property {number[]} All of the modes for which this mapping applies. */ modes: null, - /** @property {string[]} All of this mapping's names (key sequences). */ - names: null, /** @property {function (number)} The function called to execute this mapping. */ action: null, /** @property {string} This mapping's description, as shown in :listkeys. */ diff --git a/common/content/statusline.js b/common/content/statusline.js index fd70dd82..46b9b624 100644 --- a/common/content/statusline.js +++ b/common/content/statusline.js @@ -22,6 +22,7 @@ var StatusLine = Module("statusline", { #addon-bar > #addonbar-closebutton { visibility: collapse; } #addon-bar > xul|toolbarspring { visibility: collapse; } ]]>); + highlight.loadCSS(util.compileMacro(