1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-22 15:48:00 +01:00

merge refactored key event handlers

This commit is contained in:
Doug Kearns
2007-09-19 12:25:45 +00:00
parent 3baf614b11
commit ba33ed5b13
2 changed files with 113 additions and 92 deletions

View File

@@ -46,17 +46,14 @@ function Events() //{{{
tabcontainer.addEventListener("TabOpen", function(event) { tabcontainer.addEventListener("TabOpen", function(event) {
vimperator.statusline.updateTabCount(); vimperator.statusline.updateTabCount();
vimperator.buffer.updateBufferList(); vimperator.buffer.updateBufferList();
//vimperator.setMode(); // trick to reshow the mode in the command line
}, false); }, false);
tabcontainer.addEventListener("TabClose", function(event) { tabcontainer.addEventListener("TabClose", function(event) {
vimperator.statusline.updateTabCount() vimperator.statusline.updateTabCount()
vimperator.buffer.updateBufferList(); vimperator.buffer.updateBufferList();
//vimperator.setMode(); // trick to reshow the mode in the command line
}, false); }, false);
tabcontainer.addEventListener("TabSelect", function(event) { tabcontainer.addEventListener("TabSelect", function(event) {
vimperator.statusline.updateTabCount(); vimperator.statusline.updateTabCount();
vimperator.buffer.updateBufferList(); vimperator.buffer.updateBufferList();
//vimperator.setMode(); // trick to reshow the mode in the command line
vimperator.tabs.updateSelectionHistory(); vimperator.tabs.updateSelectionHistory();
setTimeout(vimperator.focusContent, 10); // just make sure, that no widget has focus setTimeout(vimperator.focusContent, 10); // just make sure, that no widget has focus
}, false); }, false);
@@ -72,12 +69,10 @@ function Events() //{{{
vimperator.setMode(); // trick to reshow the mode in the command line vimperator.setMode(); // trick to reshow the mode in the command line
}, null); }, null);
//
/////////////////////////////////////////////////////////
// track if a popup is open or the menubar is active // track if a popup is open or the menubar is active
//
var active_menubar = false; var active_menubar = false;
function enterPopupMode(event) function enterPopupMode(event)
{ {
if (event.originalTarget.localName == "tooltip" || event.originalTarget.id == "vimperator-visualbell") if (event.originalTarget.localName == "tooltip" || event.originalTarget.id == "vimperator-visualbell")
@@ -85,35 +80,31 @@ function Events() //{{{
vimperator.addMode(null, vimperator.modes.MENU); vimperator.addMode(null, vimperator.modes.MENU);
} }
function exitPopupMode() function exitPopupMode()
{ {
// gContextMenu is set to NULL by firefox, when a context menu is closed // gContextMenu is set to NULL by firefox, when a context menu is closed
if (!gContextMenu && !active_menubar) if (!gContextMenu && !active_menubar)
vimperator.removeMode(null, vimperator.modes.MENU); vimperator.removeMode(null, vimperator.modes.MENU);
} }
function enterMenuMode() function enterMenuMode()
{ {
active_menubar = true; active_menubar = true;
vimperator.addMode(null, vimperator.modes.MENU) vimperator.addMode(null, vimperator.modes.MENU)
} }
function exitMenuMode() function exitMenuMode()
{ {
active_menubar = false; active_menubar = false;
vimperator.removeMode(null, vimperator.modes.MENU); vimperator.removeMode(null, vimperator.modes.MENU);
} }
window.addEventListener("popupshown", enterPopupMode, true); window.addEventListener("popupshown", enterPopupMode, true);
window.addEventListener("popuphidden", exitPopupMode, true); window.addEventListener("popuphidden", exitPopupMode, true);
window.addEventListener("DOMMenuBarActive", enterMenuMode, true); window.addEventListener("DOMMenuBarActive", enterMenuMode, true);
window.addEventListener("DOMMenuBarInactive", exitMenuMode, true); window.addEventListener("DOMMenuBarInactive", exitMenuMode, true);
//window.document.addEventListener("DOMTitleChanged", function(event) // window.document.addEventListener("DOMTitleChanged", function(event)
//{ // {
// //alert("titlechanged"); // vimperator.log("titlechanged");
//}, null); // }, null);
// NOTE: the order of ["Esc", "Escape"] or ["Escape", "Esc"] // NOTE: the order of ["Esc", "Escape"] or ["Escape", "Esc"]
// matters, so use that string as the first item, that you // matters, so use that string as the first item, that you
@@ -230,9 +221,8 @@ function Events() //{{{
// code which is only relevant if the page load is the current tab goes here: // code which is only relevant if the page load is the current tab goes here:
if (doc == getBrowser().selectedBrowser.contentDocument) if (doc == getBrowser().selectedBrowser.contentDocument)
{ {
/* none yet */ // we want to stay in command mode after a page has loaded
//vimperator.statusline.updateUrl(); setTimeout(vimperator.focusContent, 10);
//logMessage("onpageLoad");
} }
} }
} }
@@ -243,7 +233,7 @@ function Events() //{{{
this.destroy = function() this.destroy = function()
{ {
// BIG TODO: removeEventListeners() to avoid mem leaks // removeEventListeners() to avoid mem leaks
window.dump("TODO: remove all eventlisteners\n"); window.dump("TODO: remove all eventlisteners\n");
getBrowser().removeProgressListener(this.progressListener); getBrowser().removeProgressListener(this.progressListener);
@@ -252,6 +242,9 @@ function Events() //{{{
window.removeEventListener("popuphidden", exitPopupMode, true); window.removeEventListener("popuphidden", exitPopupMode, true);
window.removeEventListener("DOMMenuBarActive", enterMenuMode, true); window.removeEventListener("DOMMenuBarActive", enterMenuMode, true);
window.removeEventListener("DOMMenuBarInactive", exitMenuMode, true); window.removeEventListener("DOMMenuBarInactive", exitMenuMode, true);
window.removeEventListener("keypress", this.onKeyPress, true);
window.removeEventListener("keydown", this.onKeyDown, true);
} }
// This method pushes keys into the event queue from vimperator // This method pushes keys into the event queue from vimperator
@@ -262,7 +255,7 @@ function Events() //{{{
// if you want < to be taken literally, prepend it with a \\ // if you want < to be taken literally, prepend it with a \\
this.feedkeys = function(keys) this.feedkeys = function(keys)
{ {
var doc = window.content.document; var doc = window.document;
var view = window.document.defaultView; var view = window.document.defaultView;
var escapeKey = false; // \ to escape some special keys var escapeKey = false; // \ to escape some special keys
@@ -304,13 +297,13 @@ function Events() //{{{
i += matches[0].length + 1; i += matches[0].length + 1;
} }
} }
var evt = doc.createEvent('KeyEvents');
evt.initKeyEvent('keypress', true, true, view, ctrl, alt, shift, meta, keyCode, charCode );
var elem = window.document.commandDispatcher.focusedElement; var elem = window.document.commandDispatcher.focusedElement;
if (!elem) if (!elem)
elem = window; elem = window.content;
var evt = doc.createEvent("KeyEvents");
evt.initKeyEvent("keypress", true, true, view, ctrl, alt, shift, meta, keyCode, charCode );
elem.dispatchEvent(evt); elem.dispatchEvent(evt);
} }
} }
@@ -364,10 +357,6 @@ function Events() //{{{
if (modifier.length == 0) if (modifier.length == 0)
return key; return key;
} }
if (key == null)
return null;
} }
else if (event.type == "click" || event.type == "dblclick") else if (event.type == "click" || event.type == "dblclick")
{ {
@@ -408,10 +397,17 @@ function Events() //{{{
return (key == "<Esc>" || key == "<C-[>" || key == "<C-c>"); return (key == "<Esc>" || key == "<C-[>" || key == "<C-c>");
} }
// global escape handler, is called in ALL modes
this.onEscape = function() this.onEscape = function()
{ {
if (!vimperator.hasMode(vimperator.modes.ESCAPE_ONE_KEY)) if (!vimperator.hasMode(vimperator.modes.ESCAPE_ONE_KEY))
{ {
if (vimperator.hasMode(vimperator.modes.ESCAPE_ALL_KEYS))
{
vimperator.removeMode(null, vimperator.modes.ESCAPE_ALL_KEYS);
return;
}
vimperator.setMode(vimperator.modes.NORMAL); vimperator.setMode(vimperator.modes.NORMAL);
vimperator.commandline.clear(); vimperator.commandline.clear();
vimperator.hints.disableHahMode(); vimperator.hints.disableHahMode();
@@ -420,24 +416,19 @@ function Events() //{{{
} }
} }
// this keypress handler gets always called first, even if e.g.
// the commandline has focus
this.onKeyPress = function(event) this.onKeyPress = function(event)
{ {
var key = vimperator.events.toString(event); var key = vimperator.events.toString(event);
if (!key) if (!key)
return false; return true;
// sometimes the non-content area has focus, making our keys not work
// if (event.target.id == "main-window") var stop = true; // set to false if we should NOT consume this event but let also firefox handle it
// alert("focusContent();");
if (vimperator.hasMode(vimperator.modes.MENU)) if (vimperator.hasMode(vimperator.modes.MENU))
return false; return false;
// XXX: ugly hack for now pass certain keys to firefox as they are without beeping
// also fixes key navigation in menus, etc.
if (key == "<Tab>" || key == "<Return>" || key == "<Space>" || key == "<Up>" || key == "<Down>")
return false;
// XXX: for now only, later: input mappings if form element focused // XXX: for now only, later: input mappings if form element focused
if (isFormElemFocused()) if (isFormElemFocused())
{ {
@@ -468,7 +459,7 @@ function Events() //{{{
if (vimperator.hasMode(vimperator.modes.ESCAPE_ONE_KEY) && !vimperator.hasMode(vimperator.modes.ESCAPE_ALL_KEYS)) if (vimperator.hasMode(vimperator.modes.ESCAPE_ONE_KEY) && !vimperator.hasMode(vimperator.modes.ESCAPE_ALL_KEYS))
{ {
vimperator.removeMode(null, vimperator.modes.ESCAPE_ONE_KEY); vimperator.removeMode(null, vimperator.modes.ESCAPE_ONE_KEY);
return false; return true;
} }
// handle Escape-all-keys mode (I) // handle Escape-all-keys mode (I)
if (vimperator.hasMode(vimperator.modes.ESCAPE_ALL_KEYS)) if (vimperator.hasMode(vimperator.modes.ESCAPE_ALL_KEYS))
@@ -478,10 +469,14 @@ function Events() //{{{
else if (key == "<Esc>" || key == "<C-[>" || key == "<C-v>") else if (key == "<Esc>" || key == "<C-[>" || key == "<C-v>")
; // let flow continue to handle these keys ; // let flow continue to handle these keys
else else
return false; return true;
} }
// FIXME: proper way is to have a better onFocus handler which also handles events for the XUL
if (!vimperator.hasMode(vimperator.modes.COMMAND_LINE) &&
isFormElemFocused()) // non insert mode, but e.g. the location bar has focus
return true;
if (vimperator.hasMode(vimperator.modes.COMMAND_LINE) && if (vimperator.hasMode(vimperator.modes.COMMAND_LINE) &&
vimperator.hasMode(vimperator.modes.WRITE_MULTILINE)) vimperator.hasMode(vimperator.modes.WRITE_MULTILINE))
{ {
@@ -489,6 +484,15 @@ function Events() //{{{
return false; return false;
} }
// XXX: ugly hack for now pass certain keys to firefox as they are without beeping
// also fixes key navigation in combo boxes, etc.
if (vimperator.hasMode(vimperator.modes.NORMAL))
{
if (key == "<Tab>" || key == "<S-Tab>" || key == "<Return>" || key == "<Space>" || key == "<Up>" || key == "<Down>")
return false;
}
// // FIXME: handle middle click in content area {{{ // // FIXME: handle middle click in content area {{{
// // alert(event.target.id); // // alert(event.target.id);
// if (/*event.type == 'mousedown' && */event.button == 1 && event.target.id == 'content') // if (/*event.type == 'mousedown' && */event.button == 1 && event.target.id == 'content')
@@ -515,8 +519,8 @@ function Events() //{{{
if (vimperator.hasMode(vimperator.modes.HINTS)) if (vimperator.hasMode(vimperator.modes.HINTS))
{ {
// never propagate this key to firefox, when hints are visible // never propagate this key to firefox, when hints are visible
event.preventDefault(); //event.preventDefault();
event.stopPropagation(); //event.stopPropagation();
var map = vimperator.mappings.get(vimperator.modes.HINTS, key); var map = vimperator.mappings.get(vimperator.modes.HINTS, key);
if (map) if (map)
@@ -574,7 +578,6 @@ function Events() //{{{
else // open in current window else // open in current window
vimperator.hints.openHints(false, false); vimperator.hints.openHints(false, false);
//if (vimperator.hints.currentMode() == HINT_MODE_QUICK)
if (vimperator.hasMode(vimperator.modes.QUICK_HINT)) if (vimperator.hasMode(vimperator.modes.QUICK_HINT))
vimperator.hints.disableHahMode(); vimperator.hints.disableHahMode();
else // ALWAYS mode else // ALWAYS mode
@@ -587,8 +590,7 @@ function Events() //{{{
return true; return true;
} }
if (vimperator.hasMode(vimperator.modes.NORMAL))
{
var count_str = vimperator.input.buffer.match(/^[0-9]*/)[0]; var count_str = vimperator.input.buffer.match(/^[0-9]*/)[0];
var candidate_command = (vimperator.input.buffer + key).replace(count_str, ''); var candidate_command = (vimperator.input.buffer + key).replace(count_str, '');
var map; var map;
@@ -596,21 +598,20 @@ function Events() //{{{
// counts must be at the start of a complete mapping (10j -> go 10 lines down) // counts must be at the start of a complete mapping (10j -> go 10 lines down)
if ((vimperator.input.buffer + key).match(/^[1-9][0-9]*$/)) if ((vimperator.input.buffer + key).match(/^[1-9][0-9]*$/))
{ {
// no count for insert mode mappings
if (vimperator.hasMode(vimperator.modes.COMMAND_LINE))
stop = false;
else
vimperator.input.buffer += key; vimperator.input.buffer += key;
vimperator.statusline.updateInputBuffer(vimperator.input.buffer);
return true;
} }
else if (vimperator.input.pendingArgMap)
if (vimperator.input.pendingMap)
{ {
vimperator.input.buffer = ""; vimperator.input.buffer = "";
if (key != "<Esc>" && key != "<C-[>") if (key != "<Esc>" && key != "<C-[>")
vimperator.input.pendingMap.execute(null, vimperator.input.count, key); vimperator.input.pendingArgMap.execute(null, vimperator.input.count, key);
vimperator.input.pendingMap = null; vimperator.input.pendingArgMap = null;
event.preventDefault();
event.stopPropagation();
} }
else if (map = vimperator.mappings.get(vimperator.modes.NORMAL, candidate_command)) else if (map = vimperator.mappings.get(vimperator.modes.NORMAL, candidate_command))
{ {
@@ -619,32 +620,55 @@ function Events() //{{{
vimperator.input.count = -1; vimperator.input.count = -1;
if (map.flags & Mappings.flags.ARGUMENT) if (map.flags & Mappings.flags.ARGUMENT)
{ {
vimperator.input.pendingMap = map; vimperator.input.pendingArgMap = map;
vimperator.input.buffer += key; vimperator.input.buffer += key;
} }
else if (vimperator.input.pendingMotionMap)
{
if (key != "<Esc>" && key != "<C-[>")
{
vimperator.input.pendingMotionMap.execute(candidate_command, vimperator.input.count, null);
}
vimperator.input.pendingMotionMap = null;
vimperator.input.buffer = "";
}
// no count support for these commands yet
else if (map.flags & Mappings.flags.MOTION)
{
vimperator.input.pendingMotionMap = map;
vimperator.input.buffer = "";
}
else else
{ {
vimperator.input.buffer = ""; vimperator.input.buffer = "";
// vimperator.log("executed: " + candidate_command + " in mode: " + mode, 8);
map.execute(null, vimperator.input.count); map.execute(null, vimperator.input.count);
} }
event.preventDefault();
event.stopPropagation();
} }
else if (vimperator.mappings.getCandidates(vimperator.modes.NORMAL, candidate_command).length > 0) else if (vimperator.mappings.getCandidates(vimperator.modes.NORMAL, candidate_command).length > 0)
{ {
vimperator.input.buffer += key; vimperator.input.buffer += key;
event.preventDefault();
event.stopPropagation();
} }
else else
{ {
vimperator.input.buffer = ""; vimperator.input.buffer = "";
vimperator.input.pendingMap = null; vimperator.input.pendingArgMap = null;
vimperator.input.pendingMotionMap = null;
if (vimperator.hasMode(vimperator.modes.COMMAND_LINE))
stop = false; // command was not a vimperator command, maybe it is a firefox command
else
vimperator.beep(); vimperator.beep();
} }
if (stop)
{
event.preventDefault();
event.stopPropagation();
} }
vimperator.statusline.updateInputBuffer(vimperator.input.buffer);
var motion_map = (vimperator.input.pendingMotionMap && vimperator.input.pendingMotionMap.names[0]) || "";
vimperator.statusline.updateInputBuffer(motion_map + vimperator.input.buffer);
return false; return false;
} }
window.addEventListener("keypress", this.onKeyPress, true); window.addEventListener("keypress", this.onKeyPress, true);
@@ -655,7 +679,6 @@ function Events() //{{{
if (vimperator.hasMode(vimperator.modes.ESCAPE_ONE_KEY) || vimperator.hasMode(vimperator.modes.ESCAPE_ALL_KEYS) || isFormElemFocused()) if (vimperator.hasMode(vimperator.modes.ESCAPE_ONE_KEY) || vimperator.hasMode(vimperator.modes.ESCAPE_ALL_KEYS) || isFormElemFocused())
return true; return true;
event.preventDefault();
event.stopPropagation(); event.stopPropagation();
return false; return false;
} }
@@ -712,13 +735,10 @@ function Events() //{{{
// happens when the users switches tabs // happens when the users switches tabs
onLocationChange: function() onLocationChange: function()
{ {
// if (vimperator.hasMode(vimperator.modes.HINTS) && !vimperator.hasMode(vimperator.modes.ALWAYS_HINT))
// vimperator.hints.disableHahMode();
vimperator.statusline.updateUrl(); vimperator.statusline.updateUrl();
vimperator.statusline.updateProgress(); vimperator.statusline.updateProgress();
// if this is not delayed we get the wrong position of the old buffer // if this is not delayed we get the position of the old buffer
setTimeout(function() { vimperator.statusline.updateBufferPosition(); }, 100); setTimeout(function() { vimperator.statusline.updateBufferPosition(); }, 100);
}, },
// called at the very end of a page load // called at the very end of a page load

View File

@@ -202,7 +202,8 @@ const vimperator = (function() //{{{
input: { input: {
buffer: "", // partial command storage buffer: "", // partial command storage
pendingMap: null, // pending map storage pendingMotionMap: null, // e.g. "d{motion}" if we wait for a motion of the "d" command
pendingArgMap: null, // pending map storage for commands like m{a-z}
count: -1 // parsed count from the input buffer count: -1 // parsed count from the input buffer
}, },