diff options
Diffstat (limited to 'common/content/events.js')
-rw-r--r-- | common/content/events.js | 340 |
1 files changed, 171 insertions, 169 deletions
diff --git a/common/content/events.js b/common/content/events.js index eec282cb..dd254d4f 100644 --- a/common/content/events.js +++ b/common/content/events.js @@ -333,9 +333,6 @@ function Events() //{{{ var lastFocus = null; - var inputBufferLength = 0; // count the number of keys in input.buffer (can be different from input.buffer.length) - var skipMap = false; // while feeding the keys (stored in input.buffer | no map found) - ignore mappings - var macros = storage.newMap("macros", true); var currentMacro = ""; @@ -988,7 +985,11 @@ function Events() //{{{ let evt = doc.createEvent("KeyEvents"); evt.initKeyEvent("keypress", true, true, view, ctrl, alt, shift, meta, keyCode, charCode); - evt.noremap = !!noremap; + if (typeof noremap == "object") + for (let [k, v] in Iterator(noremap)) + event[k] = v; + else + evt.noremap = !!noremap; evt.isMacro = true; if (string) { @@ -1374,9 +1375,6 @@ function Events() //{{{ if (!key) return; - //liberator.log(key + " in mode: " + liberator.mode); - //liberator.dump(key + " in mode: " + liberator.mode); - if (modes.isRecording) { if (key == "q") // TODO: should not be hardcoded @@ -1416,114 +1414,110 @@ function Events() //{{{ } } - let stop = true; // set to false if we should NOT consume this event but let Firefox handle it - - let win = document.commandDispatcher.focusedWindow; - if (win && win.document && win.document.designMode == "on" && !config.isComposeWindow) - return; - - // menus have their own command handlers - if (modes.extended & modes.MENU) - return; - - // handle Escape-one-key mode (Ctrl-v) - if (modes.passNextKey && !modes.passAllKeys) - { - modes.passNextKey = false; - return; - } - // handle Escape-all-keys mode (Ctrl-q) - if (modes.passAllKeys) - { - if (modes.passNextKey) - modes.passNextKey = false; // and then let flow continue - else if (key == "<Esc>" || key == "<C-[>" || key == "<C-v>") - ; // let flow continue to handle these keys to cancel escape-all-keys mode - else - return; - } - - // just forward event without checking any mappings when the MOW is open - if (liberator.mode == modes.COMMAND_LINE && - (modes.extended & modes.OUTPUT_MULTILINE)) + try { - commandline.onMultilineOutputEvent(event); - return void killEvent(); - } + let stop = false; + + let win = document.commandDispatcher.focusedWindow; + if (win && win.document && win.document.designMode == "on" && !config.isComposeWindow) + stop = true; + // menus have their own command handlers + if (modes.extended & modes.MENU) + stop = true; + // handle Escape-one-key mode (Ctrl-v) + else if (modes.passNextKey && !modes.passAllKeys) + { + modes.passNextKey = false; + stop = true; + } + // handle Escape-all-keys mode (Ctrl-q) + else if (modes.passAllKeys) + { + if (modes.passNextKey) + modes.passNextKey = false; // and then let flow continue + else if (key == "<Esc>" || key == "<C-[>" || key == "<C-v>") + ; // let flow continue to handle these keys to cancel escape-all-keys mode + else + stop = true; + } - // XXX: ugly hack for now pass certain keys to Firefox 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] & liberator.mode)) - return; + if (stop) + { + input.buffer = ""; + return void killEvent(); + } - // TODO: handle middle click in content area + stop = true; // set to false if we should NOT consume this event but let Firefox handle it - if (key != "<Esc>" && key != "<C-[>") - { - // custom mode... - if (liberator.mode == modes.CUSTOM) + // just forward event without checking any mappings when the MOW is open + if (liberator.mode == modes.COMMAND_LINE && + (modes.extended & modes.OUTPUT_MULTILINE)) { - plugins.onEvent(event); + commandline.onMultilineOutputEvent(event); return void killEvent(); } - if (modes.extended & modes.HINTS) + // XXX: ugly hack for now pass certain keys to Firefox 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] & liberator.mode)) + { + input.buffer = ""; + return; + } + + // TODO: handle middle click in content area + + if (key != "<Esc>" && key != "<C-[>") { - // under HINT mode, certain keys are redirected to hints.onEvent - if (key == "<Return>" || key == "<Tab>" || key == "<S-Tab>" - || key == mappings.getMapLeader() - || (key == "<BS>" && hints.previnput == "number") - || (/^[0-9]$/.test(key) && !hints.escNumbers)) + // custom mode... + if (liberator.mode == modes.CUSTOM) { hints.onEvent(event); return void killEvent(); } - // others are left to generate the 'input' event or handled by Firefox - return; - } - } + if (modes.extended & modes.HINTS) + { + // under HINT mode, certain keys are redirected to hints.onEvent + if (key == "<Return>" || key == "<Tab>" || key == "<S-Tab>" + || key == mappings.getMapLeader() + || (key == "<BS>" && hints.previnput == "number") + || (/^[0-9]$/.test(key) && !hints.escNumbers)) + { + hints.onEvent(event); + event.preventDefault(); + event.stopPropagation(); + return void killEvent(); + } - // 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? + // others are left to generate the 'input' event or handled by Firefox + return; + } + } - if (liberator.mode == modes.CUSTOM) - return; + // 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? - let countStr = input.buffer.match(/^[0-9]*/)[0]; - let candidateCommand = (input.buffer + key).replace(countStr, ""); - let map; - if (event.noremap) - map = mappings.getDefault(liberator.mode, candidateCommand); - else - map = mappings.get(liberator.mode, candidateCommand); + if (liberator.mode == modes.CUSTOM) + return; - let candidates = mappings.getCandidates(liberator.mode, candidateCommand); - if (candidates.length == 0 && !map) - { - map = input.pendingMap; - input.pendingMap = null; - } + let inputStr = 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"](liberator.mode, candidateCommand); - // counts must be at the start of a complete mapping (10j -> go 10 lines down) - if (/^[1-9][0-9]*$/.test(input.buffer + key)) - { - // no count for insert mode mappings - if (liberator.mode == modes.INSERT || liberator.mode == modes.COMMAND_LINE) - stop = false; - else + let candidates = mappings.getCandidates(liberator.mode, candidateCommand); + if (candidates.length == 0 && !map) { - input.buffer += key; - inputBufferLength++; + map = input.pendingMap; + input.pendingMap = null; } - } - else if (input.pendingArgMap) - { + input.buffer = ""; inputBufferLength = 0; let tmp = input.pendingArgMap; // must be set to null before .execute; if not @@ -1532,100 +1526,108 @@ function Events() //{{{ { if (modes.isReplaying && !waitForPageLoaded()) return; - - tmp.execute(null, input.count, key); - } - } - // only follow a map if there isn't a longer possible mapping - // (allows you to do :map z yy, when zz is a longer mapping than z) - // TODO: map.rhs is only defined for user defined commands, should add a "isDefault" property - else if (map && !skipMap && (map.rhs || candidates.length == 0)) - { - input.pendingMap = null; - input.count = parseInt(countStr, 10); - if (isNaN(input.count)) - input.count = -1; - if (map.flags & Mappings.flags.ARGUMENT) - { - input.pendingArgMap = map; - input.buffer += key; - inputBufferLength++; } - else if (input.pendingMotionMap) + + // counts must be at the start of a complete mapping (10j -> go 10 lines down) + if (countStr && !candidateCommand) { - if (key != "<Esc>" && key != "<C-[>") - input.pendingMotionMap.execute(candidateCommand, input.count, null); - input.pendingMotionMap = null; - input.buffer = ""; - inputBufferLength = 0; + // no count for insert mode mappings + if (liberator.mode == modes.INSERT || liberator.mode == modes.COMMAND_LINE) + stop = false; + else + input.buffer = inputStr; } - // no count support for these commands yet - else if (map.flags & Mappings.flags.MOTION) + else if (input.pendingArgMap) { - input.pendingMotionMap = map; input.buffer = ""; - inputBufferLength = 0; + let tmp = input.pendingArgMap; // must be set to null before .execute; if not + input.pendingArgMap = null; // input.pendingArgMap is still 'true' also for new feeded keys + if (key != "<Esc>" && key != "<C-[>") + { + if (modes.isReplaying && !waitForPageLoaded()) + return; + + tmp.execute(null, input.count, key); + } } - else + // only follow a map if there isn't a longer possible mapping + // (allows you to do :map z yy, when zz is a longer mapping than z) + // TODO: map.rhs is only defined for user defined commands, should add a "isDefault" property + else if (map && !event.skipmap && (map.rhs || candidates.length == 0)) { + input.pendingMap = null; + input.count = parseInt(countStr, 10); + if (isNaN(input.count)) + input.count = -1; input.buffer = ""; - inputBufferLength = 0; - - if (modes.isReplaying && !waitForPageLoaded()) - return; + if (map.flags & Mappings.flags.ARGUMENT) + { + input.buffer = inputStr; + input.pendingArgMap = map; + } + else if (input.pendingMotionMap) + { + input.buffer = ""; + if (key != "<Esc>" && key != "<C-[>") + input.pendingMotionMap.execute(candidateCommand, input.count, null); + input.pendingMotionMap = null; + } + // no count support for these commands yet + else if (map.flags & Mappings.flags.MOTION) + { + input.pendingMotionMap = map; + } + else + { + if (modes.isReplaying && !waitForPageLoaded()) + return void killEvent(); - let ret = map.execute(null, input.count); - if (map.flags & Mappings.flags.ALLOW_EVENT_ROUTING && ret) - stop = false; + let ret = map.execute(null, input.count); + if (map.flags & Mappings.flags.ALLOW_EVENT_ROUTING && ret) + stop = false; + } } - } - else if (mappings.getCandidates(liberator.mode, candidateCommand).length > 0 && !skipMap) - { - input.pendingMap = map; - input.buffer += key; - inputBufferLength++; - } - 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 (input.buffer != "" && !skipMap && - (liberator.mode & (modes.INSERT | modes.COMMAND_LINE | modes.TEXTAREA))) + else if (mappings.getCandidates(liberator.mode, candidateCommand).length > 0 && !event.skipmap) { - // no map found -> refeed stuff in input.buffer (only while in INSERT, CO... modes) - skipMap = true; // ignore maps while doing so - events.feedkeys(input.buffer, true); + input.pendingMap = map; + input.buffer += key; } - if (skipMap) + else // if the key is neither a mapping nor the start of one { - if (--inputBufferLength == 0) // inputBufferLength == 0. input.buffer refeeded... - skipMap = false; // done... - } + // the mode checking is necessary so that things like g<esc> do not beep + if (input.buffer != "" && !event.skipmap && + (liberator.mode & (modes.INSERT | modes.COMMAND_LINE | modes.TEXTAREA))) + events.feedkeys(input.buffer, { noremap: true, skipmap: true }); - input.buffer = ""; - input.pendingArgMap = null; - input.pendingMotionMap = null; - input.pendingMap = null; - - if (key != "<Esc>" && key != "<C-[>") - { - // allow key to be passed to Firefox if we can't handle it - stop = false; + input.buffer = ""; + input.pendingArgMap = null; + input.pendingMotionMap = null; + input.pendingMap = null; - if (liberator.mode == modes.COMMAND_LINE) + if (key != "<Esc>" && key != "<C-[>") { - if (!(modes.extended & modes.INPUT_MULTILINE)) - commandline.onEvent(event); // reroute event in command line mode + // allow key to be passed to Firefox if we can't handle it + stop = false; + + if (liberator.mode == modes.COMMAND_LINE) + { + if (!(modes.extended & modes.INPUT_MULTILINE)) + commandline.onEvent(event); // reroute event in command line mode + } + else if (liberator.mode != modes.INSERT && liberator.mode != modes.TEXTAREA) + liberator.beep(); } - else if (liberator.mode != modes.INSERT && liberator.mode != modes.TEXTAREA) - liberator.beep(); } - } - - if (stop) - killEvent(); - let motionMap = (input.pendingMotionMap && input.pendingMotionMap.names[0]) || ""; - statusline.updateInputBuffer(motionMap + input.buffer); + if (stop) + killEvent() + } + finally + { + let motionMap = (input.pendingMotionMap && input.pendingMotionMap.names[0]) || ""; + statusline.updateInputBuffer(motionMap + input.buffer); + } + return false; }, // this is need for sites like msn.com which focus the input field on keydown |