diff --git a/common/content/editor.js b/common/content/editor.js index 27c0c444..5a31c878 100644 --- a/common/content/editor.js +++ b/common/content/editor.js @@ -1161,14 +1161,16 @@ var Editor = Module("editor", XPCOM(Ci.nsIEditActionListener, ModuleBase), { "<*-Home>", "<*-End>", "<*-PageUp>", "<*-PageDown>", "", "", "<*-Tab>"], "Handled by " + config.host, - () => Events.PASS_THROUGH); + () => Events.PASS, + { passThrough: true }); mappings.add([modes.INSERT], ["", ""], "Expand Insert mode abbreviation", function () { editor.expandAbbreviation(modes.INSERT); - return Events.PASS_THROUGH; - }); + return Events.PASS; + }, + { passThrough: true }); mappings.add([modes.INSERT], ["", ""], "Expand Insert mode abbreviation", diff --git a/common/content/events.js b/common/content/events.js index b4d94edb..05bcc157 100644 --- a/common/content/events.js +++ b/common/content/events.js @@ -784,21 +784,43 @@ var Events = Module("events", { let key = DOM.Event.stringify(event); - let pass = this.passing && !event.isMacro || - DOM.Event.feedingEvent && DOM.Event.feedingEvent.isReplay || - event.isReplay || - modes.main == modes.PASS_THROUGH || - modes.main == modes.QUOTE - && modes.getStack(1).main !== modes.PASS_THROUGH - && !this.shouldPass(event) || - !modes.passThrough && this.shouldPass(event) || - !this.processor && event.type === "keydown" - && options.get("passunknown").getKey(modes.main.allBases) - && !(modes.main.count && /^\d$/.test(key) || - modes.main.allBases.some( - mode => mappings.hives - .some(hive => hive.get(mode, key) - || hive.getCandidates(mode, key)))); + let hasCandidates = mode => { + return mappings.hives.some(hive => (hive.get(mode, key, true) || + hive.getCandidates(mode, key, true))); + }; + + let pass = (() => { + if (this.passing && !event.isMacro) + return true; + + if (DOM.Event.feedingEvent && DOM.Event.feedingEvent.isReplay) + return true; + + if (event.isReplay) + return true; + + if (modes.main == modes.PASS_THROUGH) + return true; + + if (modes.main == modes.QUOTE && + modes.getStack(1).main !== modes.PASS_THROUGH && + !this.shouldPass(event)) + return true; + + if (!modes.passThrough && this.shouldPass(event)) + return true; + + if (!this.processor && event.type === "keydown" && + options.get("passunknown").getKey(modes.main.allBases)) { + if (!(modes.main.count && /^\d$/.test(key))) + return true; + + if (modes.main.allBases.some(hasCandidates)) + return true; + } + + return false; + })(); events.dbg("ON " + event.type.toUpperCase() + " " + key + " passing: " + this.passing + " " + diff --git a/common/content/mappings.js b/common/content/mappings.js index 00bb4a77..d7fe8b38 100644 --- a/common/content/mappings.js +++ b/common/content/mappings.js @@ -84,6 +84,8 @@ var Map = Class("Map", { /** @property {boolean} Whether the RHS of the mapping should expand mappings recursively. */ noremap: false, + passThrough: true, + /** @property {function(object)} A function to be executed before this mapping. */ preExecute: function preExecute(args) {}, /** @property {function(object)} A function to be executed after this mapping. */ @@ -232,10 +234,13 @@ var MapHive = Class("MapHive", Contexts.Hive, { * * @param {Modes.Mode} mode The mode to search. * @param {string} cmd The map name to match. + * @param {boolean} skipPassThrough Ignore pass-through mappings. * @returns {Map|null} */ - get: function (mode, cmd) { - return this.getStack(mode).mappings[cmd]; + get: function (mode, cmd, skipPassThrough = false) { + let map = this.getStack(mode).mappings[cmd]; + if (!(skipPassThrough && map.passThrough)) + return map; }, /** @@ -244,9 +249,12 @@ var MapHive = Class("MapHive", Contexts.Hive, { * * @param {Modes.Mode} mode The mode to search. * @param {string} prefix The map prefix string to match. + * @param {boolean} skipPassThrough Ignore pass-through mappings. * @returns {number) */ - getCandidates: function (mode, prefix) { + getCandidates: function (mode, prefix, skipPassThrough = false) { + if (skipPassThrough) + return this.getStack(mode).hardCandidates[prefix] || 0; return this.getStack(mode).candidates[prefix] || 0; }, @@ -294,9 +302,8 @@ var MapHive = Class("MapHive", Contexts.Hive, { }, { Stack: Class("Stack", Array, { init: function (ary) { - let self = ary || []; - self.__proto__ = this.__proto__; - return self; + if (ary) + this.push(...ary); }, "@@iterator": function () { @@ -304,6 +311,7 @@ var MapHive = Class("MapHive", Contexts.Hive, { }, get candidates() { return this.states.candidates; }, + get hardCandidates() { return this.states.hardCandidates; }, get mappings() { return this.states.mappings; }, add: function (map) { @@ -312,8 +320,9 @@ var MapHive = Class("MapHive", Contexts.Hive, { }, states: Class.Memoize(function () { - var states = { + let states = { candidates: {}, + hardCandidates: {}, mappings: {} }; @@ -323,8 +332,11 @@ var MapHive = Class("MapHive", Contexts.Hive, { let state = ""; for (let key of DOM.Event.iterKeys(name)) { state += key; - if (state !== name) + if (state !== name) { states.candidates[state] = (states.candidates[state] || 0) + 1; + if (!map.passThrough) + states.hardCandidates[state] = (states.hardCandidates[state] || 0) + 1; + } } } return states;