diff --git a/common/content/commandline.js b/common/content/commandline.js index be38d08f..856652ec 100644 --- a/common/content/commandline.js +++ b/common/content/commandline.js @@ -606,7 +606,7 @@ var CommandLine = Module("commandline", { if (params.pop) commandline.leave(); }, - mainMode: this.currentExtendedMode + keyModes: [this.currentExtendedMode] }); this._keepCommand = false; diff --git a/common/content/events.js b/common/content/events.js index 3dbe77e9..dccdd66e 100644 --- a/common/content/events.js +++ b/common/content/events.js @@ -959,7 +959,7 @@ var Events = Module("events", { if (overrideMode) processors = [Events.KeyProcessor(overrideMode, mode.extended)]; else { - let keyModes = array(mode.params.keyModes || []).concat([mode.params.mainMode, mode.main]).compact(); + let keyModes = array([mode.params.keyModes, mode.main, mode.main.allBases]).flatten().compact(); let hives = mappings.hives.slice(event.noremap ? -1 : 0); @@ -972,7 +972,7 @@ var Events = Module("events", { input.preExecute = mode.params.preExecute; if (mode.params.postExecute) input.postExecute = mode.params.postExecute; - if (mode.params.onEvent && i == processors.length - 1) + if (mode.params.onEvent && input.hive === mappings.builtinHive) input.fallthrough = function (event) { // Bloody hell. if (events.toString(event) === "") diff --git a/common/content/modes.js b/common/content/modes.js index 965eb4b6..a2ce5612 100644 --- a/common/content/modes.js +++ b/common/content/modes.js @@ -35,12 +35,19 @@ var Modes = Module("modes", { this.boundProperties = {}; - // main modes, only one should ever be active + this.addMode("BASE", { + char: "b", + description: "The base mode for most other modes" + }); this.addMode("NORMAL", { char: "n", description: "Active when nothing is focused", display: function () null }); + this.addMode("INPUT", { + char: "I", + description: "The base mode for input modes, including Insert and Command Line" + }); this.addMode("INSERT", { char: "i", description: "Active when an input element is focused", @@ -101,12 +108,14 @@ var Modes = Module("modes", { }); this.addMode("PASS_THROUGH", { description: "All keys but are ignored by " + config.appName, + bases: [], hidden: true }); this.addMode("QUOTE", { hidden: true, description: "The next key sequence is ignored by " + config.appName + ", unless in Pass Through mode", + bases: [], display: function () modes.getStack(1).main == modes.PASS_THROUGH ? (modes.getStack(2).main.display() || modes.getStack(2).main.name) + " (next)" : "PASS THROUGH (next)" @@ -151,7 +160,8 @@ var Modes = Module("modes", { input: true }); this.addMode("IGNORE", { hidden: true }, { - onEvent: function (event) false + onEvent: function (event) false, + bases: [] }); this.push(this.NORMAL, 0, { @@ -387,6 +397,21 @@ var Modes = Module("modes", { }, options); }, + isinstance: function (obj) + this.allBases.indexOf(obj >= 0) || callable(obj) && this instanceof obj, + + allBases: Class.memoize(function () { + let seen = {}, res = [], queue = this.bases; + for (let mode in array.iterValues(queue)) + if (!set.add(seen, mode)) { + res.push(mode); + queue.push.apply(queue, mode.bases); + } + return res; + }), + + get bases() this.input ? [modes.INPUT] : [modes.BASE], + get toStringParams() [this.name], valueOf: function () this.id, diff --git a/common/modules/base.jsm b/common/modules/base.jsm index 868a3e46..5cdae2b1 100644 --- a/common/modules/base.jsm +++ b/common/modules/base.jsm @@ -417,12 +417,19 @@ var isinstance_types = { number: Number }; function isinstance(targ, src) { + if (targ == null) + return false; + src = Array.concat(src); for (var i = 0; i < src.length; i++) { if (typeof src[i] === "string") { if (objproto.toString.call(targ) === "[object " + src[i] + "]") return true; } + else if ("isinstance" in targ) { + if (targ.isinstance(src[i])) + return true; + } else { if (targ instanceof src[i]) return true; @@ -1317,8 +1324,7 @@ var array = Class("array", Array, { * @returns {Iterator(Object)} */ iterValues: function iterValues(ary) { - let length = ary.length; - for (let i = 0; i < length; i++) + for (let i = 0; i < ary.length; i++) yield ary[i]; },