1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2026-02-13 10:25:46 +01:00

Get rid of a lot of special casing in the event loops. Merge default.

--HG--
branch : mode-refactoring
This commit is contained in:
Kris Maglione
2010-10-10 15:19:27 -04:00
parent c977268278
commit d7ff35c565
13 changed files with 129 additions and 159 deletions

View File

@@ -567,7 +567,9 @@ const CommandLine = Module("commandline", {
this._startHints = false;
if (!(modes.extended & modes.OUTPUT_MULTILINE))
modes.push(modes.COMMAND_LINE, modes.OUTPUT_MULTILINE);
modes.push(modes.COMMAND_LINE, modes.OUTPUT_MULTILINE, {
onEvent: this.closure.onMultilineOutputEvent
});
// If it's already XML, assume it knows what it's doing.
// Otherwise, white space is significant.
@@ -695,14 +697,13 @@ const CommandLine = Module("commandline", {
cancel: extra.onCancel
};
modes.push(modes.COMMAND_LINE, modes.PROMPT | extra.extended, {
enter: function (stack) { extra.enter && extra.enter(stack); },
leave: function (stack) {
commandline.leave(stack);
if (extra.leave)
extra.leave(stack);
}
});
modes.push(modes.COMMAND_LINE, modes.PROMPT | extra.extended,
update(Object.create(extra), {
leave: function leave(stack) {
commandline.leave(stack);
leave.supercall(this, stack);
}
}));
this.currentExtendedMode = modes.PROMPT;
this.widgets.prompt = !prompt ? null : [extra.promptHighlight || "Question", prompt];
@@ -934,14 +935,7 @@ const CommandLine = Module("commandline", {
}
if (event instanceof MouseEvent)
return;
if (this._startHints) {
statusline.updateInputBuffer("");
this._startHints = false;
hints.show(key, { window: win });
return;
}
return false;
function isScrollable() !win.scrollMaxY == 0;
function atEnd() win.scrollY / win.scrollMaxY >= 1;
@@ -953,7 +947,7 @@ const CommandLine = Module("commandline", {
case ":":
commandline.open(":", "", modes.EX);
return;
return false;
// down a line
case "j":
@@ -1065,9 +1059,8 @@ const CommandLine = Module("commandline", {
break;
case ";":
statusline.updateInputBuffer(";");
this._startHints = true;
break;
hints.open(";", { window: win });
return false;
// unmapped key
default:
@@ -1085,6 +1078,7 @@ const CommandLine = Module("commandline", {
}
else
commandline.updateMorePrompt(showMorePrompt, showMoreHelpPrompt);
return false;
},
getSpaceNeeded: function getSpaceNeeded() {

View File

@@ -47,17 +47,16 @@ const Events = Module("events", {
this._code_key = {};
this._key_code = {};
for (let [k, v] in Iterator(KeyEvent))
if (/^DOM_VK_(?![A-Z0-9]$)/.test(k)) {
k = k.substr(7).toLowerCase();
let names = [k.replace(/(^|_)(.)/g, function (m, n1, n2) n2.toUpperCase())
.replace(/^NUMPAD/, "k")];
if (k in this._keyTable)
names = this._keyTable[k];
this._code_key[v] = names[0];
for (let [, name] in Iterator(names))
this._key_code[name.toLowerCase()] = v;
}
for (let [k, v] in Iterator(KeyEvent)) {
k = k.substr(7).toLowerCase();
let names = [k.replace(/(^|_)(.)/g, function (m, n1, n2) n2.toUpperCase())
.replace(/^NUMPAD/, "k")];
if (k in this._keyTable)
names = this._keyTable[k];
this._code_key[v] = names[0];
for (let [, name] in Iterator(names))
this._key_code[name.toLowerCase()] = v;
}
// HACK: as Gecko does not include an event for <, we must add this in manually.
if (!("<" in this._key_code)) {
@@ -374,7 +373,7 @@ const Events = Module("events", {
* @param {string} keys The string to parse.
* @returns {Array[Object]}
*/
fromString: function (input) {
fromString: function (input, unknownOk) {
let out = [];
let re = RegExp("<.*?>?>|[^<]|<(?!.*>)", "g");
@@ -388,9 +387,10 @@ const Events = Module("events", {
let [match, modifier, keyname] = evt_str.match(/^<((?:[CSMA]-)*)(.+?)>$/i) || [false, '', ''];
modifier = modifier.toUpperCase();
keyname = keyname.toLowerCase();
evt_obj.dactylKeyname = keyname;
if (keyname && !(keyname.length == 1 && modifier.length == 0 || // disallow <> and <a>
!(keyname.length == 1 || this._key_code[keyname] || keyname == "nop" || /mouse$/.test(keyname)))) { // disallow <misteak>
!(unknownOk || keyname.length == 1 || this._key_code[keyname] || keyname == "nop" || /mouse$/.test(keyname)))) { // disallow <misteak>
evt_obj.ctrlKey = /C-/.test(modifier);
evt_obj.altKey = /A-/.test(modifier);
evt_obj.shiftKey = /S-/.test(modifier);
@@ -504,7 +504,7 @@ const Events = Module("events", {
else if (charCode > 0) {
key = String.fromCharCode(charCode);
if (key in this._key_code) {
if (!/^[a-z0-9]$/i.test(key) && key in this._key_code) {
// a named charcode key (<Space> and <lt>) space can be shifted, <lt> must be forced
if ((key.match(/^\s$/) && event.shiftKey) || event.dactylShift)
modifier += "S-";
@@ -786,7 +786,7 @@ const Events = Module("events", {
try {
let stop = false;
let mode = modes.main;
let mode = modes.getStack(0);
let win = document.commandDispatcher.focusedWindow;
if (win && win.document && "designMode" in win.document && win.document.designMode == "on" && !config.isComposeWindow)
@@ -804,7 +804,7 @@ const Events = Module("events", {
// handler to escape the <Esc> key
if (!stop || !isEscape(key))
modes.pop();
mode = modes.getStack(1).main;
mode = modes.getStack(1);
}
// handle Escape-all-keys mode (Ctrl-q)
@@ -815,66 +815,32 @@ const Events = Module("events", {
stop = true; // set to false if we should NOT consume this event but let the host app handle it
// just forward event without checking any mappings when the MOW is open
if (mode == modes.COMMAND_LINE && (modes.extended & modes.OUTPUT_MULTILINE)) {
commandline.onMultilineOutputEvent(event);
return killEvent();
}
// XXX: ugly hack for now pass certain keys to the host app as
// they are without beeping also fixes key navigation in combo
// boxes, submitting forms, etc.
// FIXME: breaks iabbr for now --mst
if (key in config.ignoreKeys && (config.ignoreKeys[key] & mode)) {
if (key in config.ignoreKeys && (config.ignoreKeys[key] & mode.main)) {
this._input.buffer = "";
return null;
}
// TODO: handle middle click in content area
if (mode.params.onEvent) {
this._input.buffer = "";
// Bloody hell.
if (key === "<C-h>")
key = event.dactylString = "<BS>";
if (!isEscape(key)) {
// custom mode...
if (mode == modes.CUSTOM) {
plugins.onEvent(event);
return killEvent();
}
// All of these special cases for hint mode are driving
// me insane! -Kris
if (modes.extended & modes.HINTS) {
// under HINT mode, certain keys are redirected to hints.onEvent
if (key == "<Return>" || key == "<Tab>" || key == "<S-Tab>"
|| key == options["mapleader"]
|| (key == "<BS>" && hints.prevInput == "number")
|| (hints.isHintKey(key) && !hints.escNumbers)) {
hints.onEvent(event);
this._input.buffer = "";
return killEvent();
}
// others are left to generate the 'input' event or handled by the host app
return null;
}
}
// FIXME (maybe): (is an ESC or C-] here): on HINTS mode, it enters
// into 'if (map && !skipMap) below. With that (or however) it
// triggers the onEscape part, where it resets mode. Here I just
// return true, with the effect that it also gets to there (for
// whatever reason). if that happens to be correct, well..
// XXX: why not just do that as well for HINTS mode actually?
if (mode == modes.CUSTOM)
if (mode.params.onEvent(event) === false)
killEvent();
return null;
let mainMode = modes.getMode(mode);
}
let inputStr = this._input.buffer + key;
let countStr = inputStr.match(/^[1-9][0-9]*|/)[0];
let candidateCommand = inputStr.substr(countStr.length);
let map = mappings[event.noremap ? "getDefault" : "get"](mode, candidateCommand);
let map = mappings[event.noremap ? "getDefault" : "get"](mode.main, candidateCommand);
let candidates = mappings.getCandidates(mode, candidateCommand);
let candidates = mappings.getCandidates(mode.main, candidateCommand);
if (candidates.length == 0 && !map) {
map = this._input.pendingMap;
this._input.pendingMap = null;
@@ -885,7 +851,7 @@ const Events = Module("events", {
// counts must be at the start of a complete mapping (10j -> go 10 lines down)
if (countStr && !candidateCommand) {
// no count for insert mode mappings
if (!mainMode.count || mainMode.input)
if (!mode.mainMode.count || mode.mainMode.input)
stop = false;
else
this._input.buffer = inputStr;
@@ -930,14 +896,14 @@ const Events = Module("events", {
stop = false;
}
}
else if (mappings.getCandidates(mode, candidateCommand).length > 0 && !event.skipmap) {
else if (mappings.getCandidates(mode.main, candidateCommand).length > 0 && !event.skipmap) {
this._input.pendingMap = map;
this._input.buffer += key;
}
else { // if the key is neither a mapping nor the start of one
// the mode checking is necessary so that things like g<esc> do not beep
if (this._input.buffer != "" && !event.skipmap &&
(mode & (modes.INSERT | modes.COMMAND_LINE | modes.TEXT_EDIT)))
(mode.main & (modes.INSERT | modes.COMMAND_LINE | modes.TEXT_EDIT)))
events.feedkeys(this._input.buffer, { noremap: true, skipmap: true });
this._input.buffer = "";
@@ -947,15 +913,15 @@ const Events = Module("events", {
if (!isEscape(key)) {
// allow key to be passed to the host app if we can't handle it
stop = (mode == modes.TEXT_EDIT);
stop = (mode.main === modes.TEXT_EDIT);
if (mode == modes.COMMAND_LINE) {
if (mode.main === modes.COMMAND_LINE) {
if (!(modes.extended & modes.INPUT_MULTILINE))
dactyl.trapErrors(function () {
commandline.onEvent(event); // reroute event in command line mode
});
}
else if (!mainMode.input)
else if (!mode.mainMode.input)
dactyl.beep();
}
}

View File

@@ -352,8 +352,8 @@
<xsl:template match="dactyl:dl" mode="help-2">
<dl>
<column/>
<column/>
<column style="{@dt}"/>
<column style="{@dd}"/>
<xsl:for-each select="dactyl:dt">
<tr>
<xsl:apply-templates select="." mode="help-1"/>

View File

@@ -83,7 +83,7 @@ const Hints = Module("hints", {
this._hintNumber = 0;
this._hintString = "";
statusline.updateInputBuffer("");
commandline.command = "";
commandline.widgets.command = "";
}
this._pageHints = [];
this._validHints = [];
@@ -97,9 +97,9 @@ const Hints = Module("hints", {
if (!this._usedTabKey) {
this._hintNumber = 0;
}
if (this.__continue && this._validHints.length <= 1) {
if (this._continue && this._validHints.length <= 1) {
this._hintString = "";
commandline.command = this._hintString;
commandline.widgets.command = this._hintString;
this._showHints();
}
this._updateStatusline();
@@ -347,8 +347,10 @@ const Hints = Module("hints", {
let prefix = (elem.getAttributeNS(NS, "class") || "") + " ";
if (active)
elem.setAttributeNS(NS, "highlight", prefix + "HintActive");
else
else if (active != null)
elem.setAttributeNS(NS, "highlight", prefix + "HintElem");
else
elem.removeAttributeNS(NS, "highlight");
},
/**
@@ -429,7 +431,6 @@ const Hints = Module("hints", {
*/
_removeHints: function (timeout, slight) {
for (let [,{ doc: doc, start: start, end: end }] in Iterator(this._docs)) {
util.dump(String(doc), start, end);
for (let elem in util.evaluateXPath("//*[@dactyl:highlight='hints']", doc))
elem.parentNode.removeChild(elem);
for (let i in util.range(start, end + 1))
@@ -489,12 +490,10 @@ const Hints = Module("hints", {
let n = 5;
(function next() {
this._setClass(elem, n % 2);
util.dump(n, String(this._top));
let hinted = n || this._validHints.some(function (e) e === elem);
this._setClass(elem, n ? n % 2 : !hinted ? null : this._validHints[Math.max(0, this._hintNumber-1)] === elem);
if (n--)
this.timeout(next, 50);
else if (!this._validHints.some(function (h) h.elem == elem))
elem.removeAttributeNS(NS, "highlight");
}).call(this);
this.timeout(function () {
@@ -765,6 +764,20 @@ const Hints = Module("hints", {
*/
isHintKey: function (key) this.hintKeys.indexOf(key) >= 0,
open: function (mode, opts) {
this._extendedhintCount = opts.count;
commandline.input(";", null, {
promptHighlight: "Normal",
completer: function (context) {
context.compare = function () 0;
context.completions = [[k, v.prompt] for ([k, v] in Iterator(hints._hintModes))];
},
onAccept: function (arg) { arg && util.timeout(function () hints.show(arg, opts), 0); },
get onCancel() this.onAccept,
onChange: function () { modes.pop(); }
});
},
/**
* Updates the display of hints.
*
@@ -782,7 +795,8 @@ const Hints = Module("hints", {
if (!stack.push)
hints.hide();
},
onChange: this.closure._onInput
onChange: this.closure._onInput,
onEvent: this.closure.onEvent
});
modes.extended = modes.HINTS;
@@ -864,9 +878,12 @@ const Hints = Module("hints", {
}
this._showActiveHint(this._hintNumber, oldId);
this._updateStatusline();
return;
return false;
case "<BS>":
if (this.prevInput !== "number")
return true;
if (this._hintNumber > 0 && !this._usedTabKey) {
this._hintNumber = Math.floor(this._hintNumber / this.hintKeys.length);
if (this._hintNumber == 0)
@@ -886,10 +903,10 @@ const Hints = Module("hints", {
this._hintNumber = 0;
this._updateStatusline();
return;
return false;
default:
if (this.isHintKey(key)) {
if (!this.escNumbers && this.isHintKey(key)) {
this.prevInput = "number";
let oldHintNumber = this._hintNumber;
@@ -914,8 +931,9 @@ const Hints = Module("hints", {
dactyl.assert(this._hintNumber != 0);
this._checkUnique();
return;
return false;
}
return true;
}
this._updateStatusline();
@@ -927,6 +945,7 @@ const Hints = Module("hints", {
this._showHints();
this._processHints(followFirst);
}
return false;
}
//}}}
}, {
@@ -1052,30 +1071,15 @@ const Hints = Module("hints", {
"Start QuickHint mode, but open link in a new tab",
function () { hints.show(options.get("activate").has("links") ? "t" : "b"); });
function inputOpts(opts) ({
promptHighlight: "Normal",
completer: function (context) {
context.compare = function () 0;
context.completions = [[k, v.prompt] for ([k, v] in Iterator(hints._hintModes))];
},
onAccept: function (arg) { arg && util.timeout(function () hints.show(arg, opts), 0); },
onChange: function () { modes.pop(); },
onCancel: function (arg) { arg && util.timeout(function () hints.show(arg, opts), 0); }
});
mappings.add(myModes, [";"],
"Start an extended hint mode",
function (count) {
this._extendedhintCount = count;
commandline.input(";", null, inputOpts());
}, { count: true });
function (count) { hints.open(";", { count: count }); },
{ count: true });
mappings.add(myModes, ["g;"],
"Start an extended hint mode and stay there until <Esc> is pressed",
function (count) {
this._extendedhintCount = count;
commandline.input("g;", null, inputOpts({ continue: true }));
}, { count: true });
function (count) { hints.open("g;", { continue: true, count: count }); },
{ count: true });
},
options: function () {
const DEFAULT_HINTTAGS =