1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-21 20:07:59 +01:00

rewrote mode-handling

This commit is contained in:
Martin Stubenschrott
2007-05-18 04:13:27 +00:00
parent 71189214c5
commit ac7c396023
6 changed files with 443 additions and 458 deletions

View File

@@ -76,7 +76,7 @@ var g_commands = [/*{{{*/
["beep"], ["beep"],
"Play a system beep", "Play a system beep",
null, null,
beep, function() { /*vimperator.*/beep(); },
null null
], ],
[ [
@@ -144,7 +144,7 @@ var g_commands = [/*{{{*/
["ec[ho]"], ["ec[ho]"],
"Display a string at the bottom of the window", "Display a string at the bottom of the window",
"Echo all arguments of this command. Useful for showing informational messages.<br/>Multiple lines WILL be seperated by \\n.", "Echo all arguments of this command. Useful for showing informational messages.<br/>Multiple lines WILL be seperated by \\n.",
echo, function(args) { vimperator.echo(args); } ,
null null
], ],
[ [
@@ -152,7 +152,7 @@ var g_commands = [/*{{{*/
["echoe[rr]"], ["echoe[rr]"],
"Display an error string at the bottom of the window", "Display an error string at the bottom of the window",
"Echo all arguments of this command highlighted in red. Useful for showing important messages.<br/>Multiple lines WILL be seperated by \\n.", "Echo all arguments of this command highlighted in red. Useful for showing important messages.<br/>Multiple lines WILL be seperated by \\n.",
echoerr, function(args) { vimperator.echoerr(args); } ,
null null
], ],
[ [
@@ -526,7 +526,7 @@ var g_mappings = [/*{{{*/
["b {number}"], ["b {number}"],
"Open a prompt to switch buffers", "Open a prompt to switch buffers",
"Typing the corresponding number opens switches to this buffer", "Typing the corresponding number opens switches to this buffer",
function (args) { /*bufshow("", true); */vimperator.commandline.open(":", "buffer ", MODE_EX); } function (args) { vimperator.commandline.open(":", "buffer ", vimperator.modes.EX); }
], ],
[ [
["B"], ["B"],
@@ -599,14 +599,14 @@ var g_mappings = [/*{{{*/
["o"], ["o"],
"Open one or more URLs in the current tab", "Open one or more URLs in the current tab",
"See <code class=\"command\">:open</code> for more details", "See <code class=\"command\">:open</code> for more details",
function(count) { vimperator.commandline.open(":", "open ", MODE_EX); } function(count) { vimperator.commandline.open(":", "open ", vimperator.modes.EX); }
], ],
[ [
["O"], ["O"],
["O"], ["O"],
"Open one ore more URLs in the current tab, based on current location", "Open one ore more URLs in the current tab, based on current location",
"Works like <code class=\"mapping\">o</code>, but preselects current URL in the <code class=\"command\">:open</code> query.", "Works like <code class=\"mapping\">o</code>, but preselects current URL in the <code class=\"command\">:open</code> query.",
function(count) { vimperator.commandline.open(":", "open " + getCurrentLocation(), MODE_EX); } function(count) { vimperator.commandline.open(":", "open " + getCurrentLocation(), vimperator.modes.EX); }
], ],
[ [
["p", "<MiddleMouse>"], ["p", "<MiddleMouse>"],
@@ -643,14 +643,14 @@ var g_mappings = [/*{{{*/
"Open one or more URLs in a new tab", "Open one or more URLs in a new tab",
"Like <code class=\"mapping\">o</code> but open URLs in a new tab.<br/>"+ "Like <code class=\"mapping\">o</code> but open URLs in a new tab.<br/>"+
"See <code class=\"command\">:tabopen</code> for more details", "See <code class=\"command\">:tabopen</code> for more details",
function(count) { vimperator.commandline.open(":", "tabopen ", MODE_EX); } function(count) { vimperator.commandline.open(":", "tabopen ", vimperator.modes.EX); }
], ],
[ [
["T"], ["T"],
["T"], ["T"],
"Open one ore more URLs in a new tab, based on current location", "Open one ore more URLs in a new tab, based on current location",
"Works like <code class=\"mapping\">t</code>, but preselects current URL in the <code class=\"command\">:tabopen</code> query.", "Works like <code class=\"mapping\">t</code>, but preselects current URL in the <code class=\"command\">:tabopen</code> query.",
function(count) { vimperator.commandline.open(":", "tabopen " + getCurrentLocation(), MODE_EX); } function(count) { vimperator.commandline.open(":", "tabopen " + getCurrentLocation(), vimperator.modes.EX); }
], ],
[ [
["u"], ["u"],
@@ -846,7 +846,7 @@ var g_mappings = [/*{{{*/
"In QuickHint mode, every hintable item (according to the <code class=\"setting\">'hinttags'</code> XPath query) is assigned a label.<br/>"+ "In QuickHint mode, every hintable item (according to the <code class=\"setting\">'hinttags'</code> XPath query) is assigned a label.<br/>"+
"If you then press the keys for a label, it is followed as soon as it can be uniquely identified and this mode is stopped. Or press <code class=\"mapping\">&lt;Esc&gt;</code> to stop this mode.<br/>"+ "If you then press the keys for a label, it is followed as soon as it can be uniquely identified and this mode is stopped. Or press <code class=\"mapping\">&lt;Esc&gt;</code> to stop this mode.<br/>"+
"If you write the hint in ALLCAPS, the hint is followed in a background tab.", "If you write the hint in ALLCAPS, the hint is followed in a background tab.",
function(count) { hah.enableHahMode(HINT_MODE_QUICK); } function(count) { hah.enableHahMode(vimperator.modes.QUICK_HINT); }
], ],
[ [
["F"], ["F"],
@@ -856,7 +856,7 @@ var g_mappings = [/*{{{*/
"If you then press the keys for a label, it is followed as soon as it can be uniquely identified. Labels stay active after following a hint in this mode, press <code class=\"mapping\">&lt;Esc&gt;</code> to stop this mode.<br/>"+ "If you then press the keys for a label, it is followed as soon as it can be uniquely identified. Labels stay active after following a hint in this mode, press <code class=\"mapping\">&lt;Esc&gt;</code> to stop this mode.<br/>"+
"This hint mode is especially useful for browsing large sites like Forums as hints are automatically regenerated when switching to a new document.<br/>"+ "This hint mode is especially useful for browsing large sites like Forums as hints are automatically regenerated when switching to a new document.<br/>"+
"Also, most <code class=\"mapping\">Ctrl</code>-prefixed shortcut keys are available in this mode for navigation.", "Also, most <code class=\"mapping\">Ctrl</code>-prefixed shortcut keys are available in this mode for navigation.",
function(count) { hah.enableHahMode(HINT_MODE_ALWAYS); } function(count) { hah.enableHahMode(vimperator.modes.ALWAYS_HINT); }
], ],
[ [
[";"], [";"],
@@ -877,7 +877,7 @@ var g_mappings = [/*{{{*/
"</ul>"+ "</ul>"+
"Multiple hints can be seperated by commas where it makes sense. <code class=\"mapping\">;ab,ac,adt</code> opens <code>AB</code>, <code>AC</code> and <code>AD</code> in a new tab.<br/>"+ "Multiple hints can be seperated by commas where it makes sense. <code class=\"mapping\">;ab,ac,adt</code> opens <code>AB</code>, <code>AC</code> and <code>AD</code> in a new tab.<br/>"+
"Hintable elements for this mode can be set in the <code class=\"setting\">'extendedhinttags'</code> XPath string.", "Hintable elements for this mode can be set in the <code class=\"setting\">'extendedhinttags'</code> XPath string.",
function(count) { hah.enableHahMode(HINT_MODE_EXTENDED); } function(count) { hah.enableHahMode(vimperator.modes.EXTENDED_HINT); }
], ],
/* search managment */ /* search managment */
@@ -916,7 +916,7 @@ var g_mappings = [/*{{{*/
[":"], [":"],
"Start command line mode", "Start command line mode",
"In command line mode, you can perform extended commands, which may require arguments.", "In command line mode, you can perform extended commands, which may require arguments.",
function(count) { vimperator.commandline.open(":", "", MODE_EX); } function(count) { vimperator.commandline.open(":", "", vimperator.modes.EX); }
], ],
[ [
["I"], ["I"],
@@ -926,7 +926,7 @@ var g_mappings = [/*{{{*/
"This is especially useful, if JavaScript controlled forms like the RichEdit form fields of GMail don't work anymore.<br/>" + "This is especially useful, if JavaScript controlled forms like the RichEdit form fields of GMail don't work anymore.<br/>" +
"To exit this mode, press <code class=\"mapping\">&lt;Esc&gt;</code>. If you also need to pass <code class=\"mapping\">&lt;Esc&gt;</code>"+ "To exit this mode, press <code class=\"mapping\">&lt;Esc&gt;</code>. If you also need to pass <code class=\"mapping\">&lt;Esc&gt;</code>"+
"in this mode to the webpage, prepend it with <code class=\"mapping\">&lt;C-v&gt;</code>.", "in this mode to the webpage, prepend it with <code class=\"mapping\">&lt;C-v&gt;</code>.",
function(count) { addMode(MODE_ESCAPE_ALL_KEYS);} function(count) { vimperator.addMode(null, vimperator.modes.ESCAPE_ALL_KEYS);}
], ],
[ [
["<C-v>"], // if you ever add/remove keys here, also check them in the onVimperatorKeypress() function ["<C-v>"], // if you ever add/remove keys here, also check them in the onVimperatorKeypress() function
@@ -935,7 +935,7 @@ var g_mappings = [/*{{{*/
"If you need to pass a certain key to a javascript form field or another extension prefix the key with <code class=\"mapping\">&lt;C-v&gt;</code>.<br/>"+ "If you need to pass a certain key to a javascript form field or another extension prefix the key with <code class=\"mapping\">&lt;C-v&gt;</code>.<br/>"+
"Also works to unshadow Firefox shortcuts like <code class=\"mapping\">&lt;C-o&gt;</code> which are otherwise hidden in Vimperator.<br/>"+ "Also works to unshadow Firefox shortcuts like <code class=\"mapping\">&lt;C-o&gt;</code> which are otherwise hidden in Vimperator.<br/>"+
"When in 'ignorekeys' mode (activated by <code class=\"mapping\">&lt;I&gt;</code>), <code class=\"mapping\">&lt;C-v&gt;</code> will pass the next key to Vimperator instead of the webpage.", "When in 'ignorekeys' mode (activated by <code class=\"mapping\">&lt;I&gt;</code>), <code class=\"mapping\">&lt;C-v&gt;</code> will pass the next key to Vimperator instead of the webpage.",
function(count) { addMode(MODE_ESCAPE_ONE_KEY); } function(count) { vimperator.addMode(null, vimperator.modes.ESCAPE_ONE_KEY); }
], ],
[ [
["<C-c>"], ["<C-c>"],
@@ -1045,7 +1045,7 @@ var g_hint_mappings = [ /*{{{*/
["y", "hah.yankUrlHints();", true, false], ["y", "hah.yankUrlHints();", true, false],
["Y", "hah.yankTextHints();", true, false], ["Y", "hah.yankTextHints();", true, false],
[",", "g_inputbuffer+=','; hah.setCurrentState(0);", false, true], [",", "g_inputbuffer+=','; hah.setCurrentState(0);", false, true],
[":", "vimperator.commandline.open(':', '', MODE_EX);", false, true], [":", "vimperator.commandline.open(':', '', vimperator.modes.EX);", false, true],
/* movement keys */ /* movement keys */
["<C-e>", "scrollBufferRelative(0, 1);", false, true], ["<C-e>", "scrollBufferRelative(0, 1);", false, true],
["<C-y>", "scrollBufferRelative(0, -1);", false, true], ["<C-y>", "scrollBufferRelative(0, -1);", false, true],
@@ -1075,31 +1075,6 @@ var g_hint_mappings = [ /*{{{*/
["<Esc>", "", true, true] ["<Esc>", "", true, true]
]; /*}}}*/ ]; /*}}}*/
//var g_searchengines = [ /*{{{*/
// ["google", "http://www.google.com/search?num=100&q=%s"],
// ["lucky", "http://www.google.com/search?num=100&q=%s&btnI=I'm%20Feeling%20Lucky"],
// ["chefkoch", "http://www.chefkoch.de/rezept-suche.php?Suchbegriff=%s"],
// ["dewiki", "http://de.wikipedia.org/wiki/%s"],
// ["discogs", "http://www.discogs.com/search?type=all&q=%s&btn=Search"],
// ["geizhals", "http://geizhals.at/?fs=%s"],
// ["imdb", "http://www.imdb.com/find?s=all&q=%s"],
// ["leo", "http://dict.leo.org/ende?search=%s"],
// ["wien", "http://members.aon.at/flole/vienna.html?UserQuery=%s&amp;ResUser=1024&amp;WidthUser=2000"],
// ["wiki", "http://en.wikipedia.org/wiki/Special:Search?search=%s&go=Go"],
// ["vim", "http://www.google.com/custom?q=%s&sa=Google+Search&cof=LW%3A125%3BL%3Ahttp%3A%2F%2Fvim.sf.net%2Fimages%2Fvim.gif%3BLH%3A60%3BAH%3Acenter%3BGL%3A0%3BS%3Ahttp%3A%2F%2Fwww.vim.org%3BAWFID%3A057fa53529d52655%3B&domains=vim.sourceforge.net%3Bwww.vim.org%3Bvimdoc.sourceforge.net&sitesearch=vim.sourceforge.net"]
//];/*}}}*/
var g_modemessages = {};
g_modemessages[MODE_NORMAL | MODE_ESCAPE_ALL_KEYS] = "ESCAPE ALL KEYS";
g_modemessages[MODE_NORMAL | MODE_ESCAPE_ONE_KEY] = "ESCAPE ONE KEY";
g_modemessages[MODE_NORMAL | MODE_ESCAPE_ALL_KEYS | MODE_ESCAPE_ONE_KEY] = "PASS ONE KEY";
g_modemessages[HINT_MODE_QUICK] = "QUICK HINT";
g_modemessages[HINT_MODE_ALWAYS] = "ALWAYS HINT";
g_modemessages[HINT_MODE_EXTENDED] = "EXTENDED HINT";
g_modemessages[MODE_NORMAL] = false;
g_modemessages[MODE_INSERT] = "INSERT";
g_modemessages[MODE_VISUAL] = "VISUAL";
// returns null, if the cmd cannot be found in our g_commands array, or // returns null, if the cmd cannot be found in our g_commands array, or
// otherwise a reference to our command // otherwise a reference to our command
function get_command(cmd) // {{{ function get_command(cmd) // {{{
@@ -1142,7 +1117,7 @@ function execute_command(count, cmd, special, args, modifiers) // {{{
if (command === null) if (command === null)
{ {
echoerr("E492: Not an editor command: " + cmd); echoerr("E492: Not an editor command: " + cmd);
focusContent(false, false); vimperator.focusContent();
return; return;
} }
@@ -1295,7 +1270,6 @@ function openURLs(str)
if (urls.length == 0) if (urls.length == 0)
return false; return false;
//getWebNavigation().loadURI(urls[0], nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null);
getBrowser().loadURI(urls[0]); getBrowser().loadURI(urls[0]);
for (var url=1; url < urls.length; url++) for (var url=1; url < urls.length; url++)
@@ -1423,9 +1397,10 @@ function isDirectory(url)
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// function stolen from Conkeror // function stolen from Conkeror
function focusNextFrame() function focusNextFrame(count)
{
try
{ {
try {
var frames = window.content.frames; var frames = window.content.frames;
if (frames.length == 0) if (frames.length == 0)
{ {
@@ -2204,45 +2179,4 @@ function toggle_images() {
message ("imageBehavior set to " + pref); message ("imageBehavior set to " + pref);
} }
////////////////////////////////////////////////////////////////////////
// mode related functions ///////////////////////////////////////// {{{1
////////////////////////////////////////////////////////////////////////
// set current mode
function setCurrentMode(mode)
{
g_current_mode = mode;
showMode();
}
// get current mode
function hasMode(mode)
{
return g_current_mode & mode;
}
// add to current mode
function addMode(mode)
{
g_current_mode |= mode;
showMode();
return g_current_mode;
}
// get current mode
function removeMode(mode)
{
g_current_mode = (g_current_mode | mode) ^ mode;
showMode();
return g_current_mode;
}
function showMode()
{
// XXX: remove
// showStatusbarMessage(g_current_mode, STATUSFIELD_INPUTBUFFER);
if (!get_pref("showmode") || !g_modemessages[g_current_mode])
return;
echo("-- " + g_modemessages[g_current_mode] + " --");
}
// vim: set fdm=marker sw=4 ts=4 et: // vim: set fdm=marker sw=4 ts=4 et:

View File

@@ -247,9 +247,9 @@ function Search()
this.gFindState = []; this.gFindState = [];
// Event handlers for search - closure is needed // Event handlers for search - closure is needed
vimperator.registerCallback("change", MODE_SEARCH, function(command){ self.searchKeyPressed(command); }); vimperator.registerCallback("change", vimperator.modes.SEARCH_FORWARD, function(command){ self.searchKeyPressed(command); });
vimperator.registerCallback("submit", MODE_SEARCH, function(command){ self.searchSubmitted(command); }); vimperator.registerCallback("submit", vimperator.modes.SEARCH_FORWARD, function(command){ self.searchSubmitted(command); });
vimperator.registerCallback("cancel", MODE_SEARCH, function(){ self.searchCancelled(); }); vimperator.registerCallback("cancel", vimperator.modes.SEARCH_FORWARD, function(){ self.searchCancelled(); });
// Called when the search dialog is asked for. Sets up everything necessary // Called when the search dialog is asked for. Sets up everything necessary
@@ -276,7 +276,7 @@ function Search()
this.gFindState.push(state); this.gFindState.push(state);
this.resumeFindState(state); this.resumeFindState(state);
vimperator.commandline.open('/', '', MODE_SEARCH); vimperator.commandline.open('/', '', vimperator.modes.SEARCH_FORWARD);
} }
// Called when the current search needs to be repeated in the forward // Called when the current search needs to be repeated in the forward
@@ -330,7 +330,8 @@ function Search()
// Called when the enter key is pressed to trigger a search // Called when the enter key is pressed to trigger a search
this.searchSubmitted = function(command) { this.searchSubmitted = function(command) {
removeMode(MODE_SEARCH); //removeMode(MODE_SEARCH);
vimperator.setMode(vimperator.modes.NORMAL);
if (this.lastFindState()["range"] == null) { if (this.lastFindState()["range"] == null) {
vimperator.echoerr("E492: Pattern not found: " + this.lastFindState()["search-str"]); vimperator.echoerr("E492: Pattern not found: " + this.lastFindState()["search-str"]);
} }
@@ -339,9 +340,10 @@ function Search()
// Called when the search is cancelled - for example if someone presses // Called when the search is cancelled - for example if someone presses
// escape while typing a search // escape while typing a search
this.searchCancelled = function() { this.searchCancelled = function() {
removeMode(MODE_SEARCH); //removeMode(MODE_SEARCH);
vimperator.setMode(vimperator.modes.NORMAL);
clearSelection(); clearSelection();
focusContent(true, true); vimperator.focusContent();
} }

View File

@@ -27,14 +27,14 @@ function hit_a_hint()
const HINT_PREFIX = 'hah_hint_'; // prefix for the hint id const HINT_PREFIX = 'hah_hint_'; // prefix for the hint id
// public accessors // public accessors
this.hintsVisible = function() { return isHahModeEnabled; }; //this.hintsVisible = function() { return isHahModeEnabled; };
this.hintedElements = function() { return hintedElems; }; this.hintedElements = function() { return hintedElems; };
this.currentState = function() { return state;}; this.currentState = function() { return state;};
this.setCurrentState = function(s) { state = s;}; this.setCurrentState = function(s) { state = s;};
this.currentMode = function() { return hintmode;}; //this.currentMode = function() { return hintmode;};
var isHahModeEnabled = false; // is typing mode on var isHahModeEnabled = false; // is typing mode on
var hintmode = HINT_MODE_QUICK; //var hintmode = HINT_MODE_QUICK;
var hintedElems = []; var hintedElems = [];
var linkNumString = ""; // the typed link number is in this string var linkNumString = ""; // the typed link number is in this string
var linkCount = 0; var linkCount = 0;
@@ -164,7 +164,8 @@ function hit_a_hint()
genElemCoords(elem); genElemCoords(elem);
// for extended hint mode, show all - even currently hidden - hints // for extended hint mode, show all - even currently hidden - hints
if (hintmode == HINT_MODE_QUICK && (elem.absoTop < area[1] || elem.absoTop > area[3] || //if (hintmode == HINT_MODE_QUICK && (elem.absoTop < area[1] || elem.absoTop > area[3] ||
if (vimperator.hasMode(vimperator.modes.QUICK_HINT) && (elem.absoTop < area[1] || elem.absoTop > area[3] ||
elem.absoLeft > area[2] || elem.absoLeft < area[0])) elem.absoLeft > area[2] || elem.absoLeft < area[0]))
continue; continue;
@@ -209,7 +210,8 @@ function hit_a_hint()
if (!win) if (!win)
win = window.content; win = window.content;
if (linkCount == 0 && hintmode != HINT_MODE_ALWAYS) //if (linkCount == 0 && hintmode != HINT_MODE_ALWAYS)
if (linkCount == 0 && !vimperator.hasMode(vimperator.modes.ALWAYS_HINT))
{ {
beep(); beep();
//alert('h'); //alert('h');
@@ -395,9 +397,9 @@ function hit_a_hint()
//function enableHahMode(event, mode) //function enableHahMode(event, mode)
this.enableHahMode = function(mode) this.enableHahMode = function(mode)
{ {
setCurrentMode(mode); //setCurrentMode(mode);
showMode(); vimperator.setMode(vimperator.modes.HINTS, mode);
hintmode = mode; //hintmode = mode;
state = 0; state = 0;
linkCount = 0; linkCount = 0;
linkNumString = ''; linkNumString = '';
@@ -424,13 +426,14 @@ function hit_a_hint()
if(!isHahModeEnabled) if(!isHahModeEnabled)
return; return;
setCurrentMode(MODE_NORMAL); //setCurrentMode(MODE_NORMAL);
vimperator.setMode(vimperator.modes.NORMAL);
isHahModeEnabled = false; isHahModeEnabled = false;
hintmode = HINT_MODE_QUICK; //hintmode = HINT_MODE_QUICK;
linkNumString = ''; linkNumString = '';
hintedElems = []; hintedElems = [];
if (!silent && get_pref("showmode")) // if (!silent && get_pref("showmode"))
vimperator.echo(''); // vimperator.echo('');
removeHints(win); removeHints(win);
return 0; return 0;
@@ -662,7 +665,8 @@ function hit_a_hint()
startCoordLoader(doc); startCoordLoader(doc);
if (hintmode == HINT_MODE_ALWAYS) //if (hintmode == HINT_MODE_ALWAYS)
if (vimperator.hasMode(vimperator.modes.ALWAYS_HINT))
{ {
state = 0; state = 0;
linkCount = 0; linkCount = 0;
@@ -677,7 +681,8 @@ function hit_a_hint()
window.document.addEventListener("pageshow", initDoc, null); window.document.addEventListener("pageshow", initDoc, null);
window.addEventListener("resize", onResize, null); window.addEventListener("resize", onResize, null);
logMessage("HAH initialized.");
logMessage("Hints initialized");
} }
var hah = new hit_a_hint(); var hah = new hit_a_hint();

View File

@@ -271,8 +271,8 @@ var g_settings = [/*{{{*/
"<code class=\"command\">:set titlestring=Mozilla Firefox</code>.", "<code class=\"command\">:set titlestring=Mozilla Firefox</code>.",
"string", "string",
null, null,
function(value) { set_pref("title", value); set_title(value); }, function(value) { set_pref("titlestring", value); set_titlestring(value); },
function() { return get_pref("title"); }, function() { return get_pref("titlestring"); },
"Vimperator", "Vimperator",
null null
], ],
@@ -500,7 +500,7 @@ function set_showtabline(value)
} }
} }
function set_title(value) function set_titlestring(value)
{ {
if (!value || typeof(value) != "string") if (!value || typeof(value) != "string")
value = get_pref("titlestring"); value = get_pref("titlestring");

View File

@@ -1,14 +1,4 @@
// XXX: move somehere else! // XXX: move somehere else!
// function save_history()
// {
// set_pref("comp_history", comp_history.join("\n"));
// }
//
// function load_history()
// {
// var hist = get_pref("comp_history", "");
// comp_history = hist.split("\n");
// }
function multiliner(line, prev_match, heredoc) function multiliner(line, prev_match, heredoc)
{ {
@@ -17,7 +7,7 @@ function multiliner(line, prev_match, heredoc)
if (prev_match[3] === undefined) prev_match[3] = ''; if (prev_match[3] === undefined) prev_match[3] = '';
if (match[4] === null) if (match[4] === null)
{ {
focusContent(false, true); // also sets tab_index to -1 vimperator.focusContent();
execute_command.apply(this, match); execute_command.apply(this, match);
} }
else else
@@ -25,7 +15,7 @@ function multiliner(line, prev_match, heredoc)
if (match[4] === false) if (match[4] === false)
{ {
prev_match[3] = prev_match[3].replace(new RegExp('<<\s*' + prev_match[4]), heredoc.replace(/\n$/, '')); prev_match[3] = prev_match[3].replace(new RegExp('<<\s*' + prev_match[4]), heredoc.replace(/\n$/, ''));
focusContent(false, true); // also sets comp_tab_index to -1 vimperator.focusContent(); // also sets comp_tab_index to -1
execute_command.apply(this, prev_match); execute_command.apply(this, prev_match);
prev_match = new Array(5); prev_match = new Array(5);
prev_match[3] = ''; prev_match[3] = '';
@@ -155,8 +145,8 @@ function CommandLine ()
prompt = ""; prompt = "";
if (!cmd) if (!cmd)
cmd = ""; cmd = "";
if (minor_mode) //if (minor_mode)
setCurrentMode(minor_mode); vimperator.setMode(vimperator.modes.COMMAND_LINE, minor_mode);
setNormalStyle(); setNormalStyle();
setPrompt(prompt); setPrompt(prompt);
@@ -228,8 +218,9 @@ function CommandLine ()
// command_line.value = ""; // command_line.value = "";
// NOTE: the command is saved to the history in the blur() handler // NOTE: the command is saved to the history in the blur() handler
focusContent(); vimperator.focusContent();
var res = vimperator.triggerCallback("submit", command); var res = vimperator.triggerCallback("submit", command);
vimperator.setMode(vimperator.modes.NORMAL, null, true);
return res; return res;
} }
/* user pressed ESCAPE to cancel this prompt */ /* user pressed ESCAPE to cancel this prompt */
@@ -238,7 +229,7 @@ function CommandLine ()
var res = vimperator.triggerCallback("cancel"); var res = vimperator.triggerCallback("cancel");
addToHistory(command); addToHistory(command);
this.clear(); this.clear();
focusContent(true, true); vimperator.focusContent();
return res; return res;
} }
@@ -412,7 +403,7 @@ function CommandLine ()
if(command.length == 0) if(command.length == 0)
{ {
this.clear(); this.clear();
focusContent(); vimperator.focusContent();
} }
} }
else // any other key else // any other key
@@ -712,9 +703,7 @@ function StatusLine()
if(!total_tabs || typeof(cur_index != "number")) if(!total_tabs || typeof(cur_index != "number"))
total_tabs = vimperator.tabs.count(); total_tabs = vimperator.tabs.count();
//var tabcount_str = "[" + cur_index.toString() + "/" + total_tabs.toString() + "]";
tabcount_widget.value = "[" + cur_index.toString() + "/" + total_tabs.toString() + "]"; tabcount_widget.value = "[" + cur_index.toString() + "/" + total_tabs.toString() + "]";
//tabcount_widget.value = tabcount_str;
}; };
// percent is given between 0 and 1 // percent is given between 0 and 1

View File

@@ -29,25 +29,6 @@ the terms of any one of the MPL, the GPL or the LGPL.
// The only global object, a handler to the main Vimperator object // The only global object, a handler to the main Vimperator object
var vimperator = null; var vimperator = null;
// major modes - FIXME: major cleanup needed
const MODE_NORMAL = 1;
const MODE_INSERT = 2;
const MODE_VISUAL = 4;
const MODE_ESCAPE_ONE_KEY = 8;
const MODE_ESCAPE_ALL_KEYS = 16;
const MODE_HINTS = 2048;
const HINT_MODE_QUICK = 32;
const HINT_MODE_ALWAYS = 64;
const HINT_MODE_EXTENDED = 128;
const MODE_COMMAND_LINE = 4096;
const MODE_EX = 256;
const MODE_SEARCH = 512;
const MODE_SEARCH_BACKWARD = 1024;
// need later?
//const MODE_BROWSER
//const MODE_CARET
var g_current_mode = MODE_NORMAL;
var popup_allowed_events; // need to change and reset this firefox pref var popup_allowed_events; // need to change and reset this firefox pref
var g_inputbuffer = ""; // here we store partial commands (e.g. 'g' if you want to type 'gg') var g_inputbuffer = ""; // here we store partial commands (e.g. 'g' if you want to type 'gg')
@@ -95,8 +76,13 @@ nsBrowserStatusHandler.prototype =
if (link == "") if (link == "")
{ {
if (ssli == 1)
vimperator.statusline.updateUrl(); vimperator.statusline.updateUrl();
showMode(); else if (ssli == 2)
{
//vimperator.echo("");
vimperator.setMode(); // trick to reshow the mode in the command line
}
} }
}, },
setJSStatus : function(status) { }, setJSStatus : function(status) { },
@@ -136,7 +122,8 @@ nsBrowserStatusHandler.prototype =
gURLBar.value = url; gURLBar.value = url;
// onLocationChange is also called when switching/deleting tabs // onLocationChange is also called when switching/deleting tabs
if (hah.currentMode() != HINT_MODE_ALWAYS) //if (hah.currentMode() != HINT_MODE_ALWAYS)
if (vimperator.hasMode(vimperator.modes.HINTS) && !vimperator.hasMode(vimperator.modes.ALWAYS_HINT))
hah.disableHahMode(); hah.disableHahMode();
vimperator.statusline.updateUrl(url); vimperator.statusline.updateUrl(url);
@@ -188,15 +175,19 @@ function init()
// these inner classes are only created here, because outside the init() // these inner classes are only created here, because outside the init()
// function, the chrome:// is not ready // function, the chrome:// is not ready
Vimperator.prototype.qm = new QM; Vimperator.prototype.qm = new QM;
// alert("ini3");
// Vimperator.prototype.commandline = new CommandLine;
Vimperator.prototype.search = new Search; Vimperator.prototype.search = new Search;
// alert("ini4");
Vimperator.prototype.previewwindow = new InformationList("vimperator-preview-window", { incremental_fill: false, max_items: 10 }); Vimperator.prototype.previewwindow = new InformationList("vimperator-preview-window", { incremental_fill: false, max_items: 10 });
// alert("ini5");
Vimperator.prototype.bufferwindow = new InformationList("vimperator-buffer-window", { incremental_fill: false, max_items: 10 }); Vimperator.prototype.bufferwindow = new InformationList("vimperator-buffer-window", { incremental_fill: false, max_items: 10 });
Vimperator.prototype.statusline = new StatusLine(); Vimperator.prototype.statusline = new StatusLine();
Vimperator.prototype.tabs = new Tabs(); Vimperator.prototype.tabs = new Tabs();
// XXX: move elsewhere // XXX: move elsewhere
vimperator.registerCallback("submit", MODE_EX, function(command) { /*vimperator.*/execute(command); } ); vimperator.registerCallback("submit", vimperator.modes.EX, function(command) { /*vimperator.*/execute(command); } );
vimperator.registerCallback("complete", MODE_EX, function(str) { return exTabCompletion(str); } ); vimperator.registerCallback("complete", vimperator.modes.EX, function(str) { return exTabCompletion(str); } );
//status_line = document.getElementById("vim-statusbar"); //status_line = document.getElementById("vim-statusbar");
command_line = document.getElementById("vim-commandbar"); command_line = document.getElementById("vim-commandbar");
@@ -316,24 +307,13 @@ function init()
// this function adds all our required listeners to react on events // this function adds all our required listeners to react on events
// also stuff like window.onScroll is handled there. // also stuff like window.onScroll is handled there.
addEventListeners(); addEventListeners();
// we always start in normal mode
setCurrentMode(MODE_NORMAL);
/*** load our preferences ***/
// load_history(); FIXME
set_showtabline(get_pref("showtabline")); set_showtabline(get_pref("showtabline"));
set_guioptions(get_pref("guioptions")); set_guioptions(get_pref("guioptions"));
set_title(); set_titlestring();
// work around firefox popup blocker // work around firefox popup blocker
popup_allowed_events = get_firefox_pref('dom.popup_allowed_events', 'change click dblclick mouseup reset submit'); popup_allowed_events = get_firefox_pref('dom.popup_allowed_events', 'change click dblclick mouseup reset submit');
@@ -348,17 +328,14 @@ function init()
if (get_pref("firsttime", true)) if (get_pref("firsttime", true))
{ {
setTimeout(function() { setTimeout(function() {
//var tab = openURLsInNewTab("about:blank", true);
//BrowserStop();
help(null, null, null, { inTab: true }); help(null, null, null, { inTab: true });
set_pref("firsttime", false); set_pref("firsttime", false);
}, 1000); }, 1000);
} }
gURLBar.blur(); gURLBar.blur();
focusContent(true, true); vimperator.focusContent();
// everything important is done, register a preload handler to speed up first time history cache // everything important is done, register a preload handler to speed up first time history cache
if(get_pref("preload")) if(get_pref("preload"))
@@ -367,11 +344,8 @@ function init()
// firefox preferences which we need to be changed to work well with vimperator // firefox preferences which we need to be changed to work well with vimperator
set_firefox_pref("browser.startup.page", 3); // start with saved session set_firefox_pref("browser.startup.page", 3); // start with saved session
// Finally, read a ~/.vimperatorrc
/* // Make sourcing asynchronous, otherwise commands that open new tabs won't work
* Finally, read a ~/.vimperatorrc
* Make sourcing asynchronous, otherwise commands that open new tabs won't work
*/
setTimeout(function() { setTimeout(function() {
source("~/.vimperatorrc", true); source("~/.vimperatorrc", true);
logMessage("~/.vimperatorrc sourced"); logMessage("~/.vimperatorrc sourced");
@@ -385,6 +359,8 @@ function unload()
/*** save our preferences ***/ /*** save our preferences ***/
vimperator.commandline.saveHistory(); vimperator.commandline.saveHistory();
// TODO: removeEventListeners();
// reset some modified firefox prefs // reset some modified firefox prefs
if (get_firefox_pref('dom.popup_allowed_events', 'change click dblclick mouseup reset submit') if (get_firefox_pref('dom.popup_allowed_events', 'change click dblclick mouseup reset submit')
== popup_allowed_events + " keypress") == popup_allowed_events + " keypress")
@@ -392,283 +368,17 @@ function unload()
} }
////////////////////////////////////////////////////////////////////////
// keyboard input handling //////////////////////////////////////// {{{1
////////////////////////////////////////////////////////////////////////
function onVimperatorKeypress(event)/*{{{*/
{
// change the event to a usable string representation
var key = keyToString(event);
//alert(key);
if (key == null)
return false;
if(event.type == "keydown")
{
logObject(event);
logObject(event.target);
return;//alert(event.target.id);
}
// sometimes the non-content area has focus, making our keys not work
// if (event.target.id == "main-window")
// alert("focusContent();");
// 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
if (isFormElemFocused())
return false;
// handle Escape-one-key mode (Ctrl-v)
if (hasMode(MODE_ESCAPE_ONE_KEY) && !hasMode(MODE_ESCAPE_ALL_KEYS))
{
removeMode(MODE_ESCAPE_ONE_KEY);
showMode();
return false;
}
// handle Escape-all-keys mode (I)
if (hasMode(MODE_ESCAPE_ALL_KEYS))
{
if(hasMode(MODE_ESCAPE_ONE_KEY))
removeMode(MODE_ESCAPE_ONE_KEY); // and then let flow continue
else if (key == "<Esc>" || key == "<C-[>" || key == "<C-v>")
; // let flow continue to handle these keys
else
return false;
}
// // FIXME: handle middle click in content area {{{
// // alert(event.target.id);
// if (/*event.type == 'mousedown' && */event.button == 1 && event.target.id == 'content')
// {
// //echo("foo " + event.target.id);
// //if (document.commandDispatcher.focusedElement == command_line.inputField)
// {
// //alert(command_line.value.substring(0, command_line.selectionStart));
// command_line.value = command_line.value.substring(0, command_line.selectionStart) +
// readFromClipboard() +
// command_line.value.substring(command_line.selectionEnd, command_line.value.length);
// alert(command_line.value);
// }
// //else
// // {
// // openURLs(readFromClipboard());
// // }
// return true;
// } }}}
// if Hit-a-hint mode is on, special handling of keys is required
// g_hint_mappings is used
// FIXME: total mess
if (hah.hintsVisible())
{
// never propagate this key to firefox, when hints are visible
event.preventDefault();
event.stopPropagation();
for (i = 0; i < g_hint_mappings.length; i++)
{
if(g_hint_mappings[i][0] == key)
{
if(g_hint_mappings[i][3] == true || hah.currentState() == 1)
{
//g_hint_mappings[i][1].call(this, event);
eval(g_hint_mappings[i][1]);
if (g_hint_mappings[i][2] == true) // stop processing this event
{
hah.disableHahMode();
g_inputbuffer = "";
vimperator.statusline.updateInputBuffer("");
return false;
}
else
{
// FIXME: make sure that YOU update the statusbar message yourself
// first in g_hint_mappings when in this mode!
vimperator.statusline.updateInputBuffer(g_inputbuffer);
return false;
}
}
}
}
// no mapping found, beep()
if (hah.currentState() == 1)
{
beep();
hah.disableHahMode();
g_inputbuffer = "";
vimperator.statusline.updateInputBuffer(g_inputbuffer);
return true;
}
// if we came here, let hit-a-hint process the key as it is part
// of a partial link
var res = hah.processEvent(event);
if (res < 0) // error occured processing this key
{
beep();
if(hah.currentMode() == HINT_MODE_QUICK)
hah.disableHahMode();
else // ALWAYS mode
hah.resetHintedElements();
g_inputbuffer = "";
}
else if (res == 0 || hah.currentMode() == HINT_MODE_EXTENDED) // key processed, part of a larger hint
g_inputbuffer += key;
else // this key completed a quick hint
{
// if the hint is all in UPPERCASE, open it in new tab
g_inputbuffer += key;
if (g_inputbuffer.toUpperCase() == g_inputbuffer)
hah.openHints(true, false);
else // open in current window
hah.openHints(false, false);
if(hah.currentMode() == HINT_MODE_QUICK)
hah.disableHahMode();
else // ALWAYS mode
hah.resetHintedElements();
g_inputbuffer = "";
}
vimperator.statusline.updateInputBuffer(g_inputbuffer);
return true;
}
// set this variable to true, if we have the start of a mapping
var couldBecomeCompleteMapping = false;
var count_str = g_inputbuffer.match(/^[0-9]*/)[0];
// counts must be at the start of a complete mapping (10j -> go 10 lines down)
if (event.charCode >= 48 && event.charCode <= 57 && !(event.ctrlKey || event.altKey))
{
if (g_inputbuffer.search(/[^0-9]/) != -1)
{
g_inputbuffer = "";
beep();
vimperator.statusline.updateInputBuffer(g_inputbuffer);
return true;
}
else
{
// handle '0' specially to allow binding of 0
if (g_inputbuffer != "" || key != "0")
{
g_inputbuffer += key;
vimperator.statusline.updateInputBuffer(g_inputbuffer);
return true;
}
// else let the flow continue, and check if 0 is a mapping
}
}
for (var i in g_mappings)
{
// each internal mapping can have multiple keys
for (var j in g_mappings[i][COMMANDS])
{
var mapping = g_mappings[i][COMMANDS][j];
// alert("key: " + key +" - mapping: "+ mapping + " - g_input: " + g_inputbuffer);
if(count_str + mapping == g_inputbuffer + key)
//if (count_str + mapping == vimperator.commandline.getCommand() + key)
{
g_count = parseInt(count_str, 10);
if (isNaN(g_count))
g_count = -1;
// allow null (= no operation) mappings
if(g_mappings[i][FUNCTION] != null)
g_mappings[i][FUNCTION].call(this, g_count);
// command executed, reset input buffer
g_inputbuffer = "";
vimperator.statusline.updateInputBuffer(g_inputbuffer);
event.preventDefault();
event.stopPropagation();
return false;
}
else if ((count_str+mapping).indexOf(g_inputbuffer + key) == 0)
//else if ((count_str+mapping).indexOf(vimperator.commandline.getCommand() + key) == 0)
{
couldBecomeCompleteMapping = true;
}
}
}
if (couldBecomeCompleteMapping)
{
g_inputbuffer += key;
event.preventDefault();
event.stopPropagation();
}
else
{
g_inputbuffer = "";
beep();
}
vimperator.statusline.updateInputBuffer(g_inputbuffer);
return false;
}/*}}}*/
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// focus and mode handling //////////////////////////////////////// {{{1 // focus and mode handling //////////////////////////////////////// {{{1
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/* After pressing Escape, put focus on a non-input field of the browser document */
function focusContent(clear_command_line, clear_statusline)
{
try
{
g_count = -1; // clear count
// if(clear_command_line)
// {
// command_line.value = "";
// command_line.inputField.setAttribute("style","font-family: monospace;");
//
// var commandBarPrompt = document.getElementById('vim-commandbar-prompt');
// commandBarPrompt.style.visibility = 'collapsed';
// commandBarPrompt.value = '';
//
// //vimperator.commandline.clear();
// }
//
// if(clear_statusline)
// {
// completion_list.hidden = true;
// comp_tab_index = COMPLETION_UNINITIALIZED;
// comp_history_index = -1;
// }
var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Components.interfaces.nsIWindowWatcher);
if (window == ww.activeWindow && document.commandDispatcher.focusedElement)
{
document.commandDispatcher.focusedElement.blur();
}
content.focus();
} catch(e)
{
vimperator.echoerr(e);
}
}
function onEscape() function onEscape()
{ {
if (!hasMode(MODE_ESCAPE_ONE_KEY)) if (!vimperator.hasMode(vimperator.modes.ESCAPE_ONE_KEY))
{ {
setCurrentMode(MODE_NORMAL); vimperator.setMode(vimperator.modes.NORMAL);
vimperator.echo("");
hah.disableHahMode(); hah.disableHahMode();
focusContent(true, true); vimperator.focusContent();
vimperator.statusline.updateUrl(); vimperator.statusline.updateUrl();
} }
} }
@@ -679,8 +389,9 @@ function onEscape()
function addEventListeners() function addEventListeners()
{ {
window.addEventListener("unload", unload, false); window.addEventListener("unload", unload, false);
window.addEventListener("keypress", onVimperatorKeypress, true);
// window.addEventListener("keydown", onVimperatorKeypress, true); window.addEventListener("keypress", vimperator.onEvent, true);
//window.addEventListener("keypress", onVimperatorKeypress, true);
// this handler is for middle click only in the content // this handler is for middle click only in the content
//window.addEventListener("mousedown", onVimperatorKeypress, true); //window.addEventListener("mousedown", onVimperatorKeypress, true);
@@ -693,11 +404,12 @@ function addEventListeners()
window.addEventListener("TabClose", vimperator.statusline.updateTabCount, false); window.addEventListener("TabClose", vimperator.statusline.updateTabCount, false);
window.addEventListener("TabSelect", function(event) window.addEventListener("TabSelect", function(event)
{ {
if (hah.currentMode == HINT_MODE_ALWAYS) // FIXME:
{ // if (hah.currentMode == HINT_MODE_ALWAYS)
hah.disableHahMode(); // {
hah.enableHahMode(HINT_MODE_ALWAYS); // hah.disableHahMode();
} // hah.enableHahMode(HINT_MODE_ALWAYS);
// }
vimperator.statusline.updateTabCount(); vimperator.statusline.updateTabCount();
}, false); }, false);
@@ -793,7 +505,7 @@ function isFormElemFocused()
tagname == "textarea" || tagname == "textarea" ||
// tagName == "SELECT" || // tagName == "SELECT" ||
// tagName == "BUTTON" || // tagName == "BUTTON" ||
tagname == "isindex") // isindex is deprecated one-line input box tagname == "isindex") // isindex is a deprecated one-line input box
return true; return true;
return false; return false;
@@ -983,13 +695,70 @@ function getLinkNodes(doc)
return links; return links;
}//}}} }//}}}
//vimperator = new function()
function Vimperator() function Vimperator()
{ {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
////////////////////// PRIVATE SECTION ///////////////////////////////////////// ////////////////////// PRIVATE SECTION /////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
this.modes = { // actually not private, but Firefox complains if this doesn't come first
// main modes
NONE: 0,
NORMAL: 1 << 0,
INSERT: 1 << 1,
VISUAL: 1 << 2,
HINTS: 1 << 3,
COMMAND_LINE: 1 << 4,
// extended modes
EX: 1 << 5,
SEARCH_FORWARD: 1 << 6,
SEARCH_BACKWARD: 1 << 7,
ESCAPE_ONE_KEY: 1 << 8,
ESCAPE_ALL_KEYS: 1 << 9,
QUICK_HINT: 1 << 10,
EXTENDED_HINT: 1 << 11,
ALWAYS_HINT: 1 << 12
}
var mode_messages = {};
mode_messages[this.modes.NORMAL] = "";
mode_messages[this.modes.INSERT] = "INSERT";
mode_messages[this.modes.VISUAL] = "VISUAL";
mode_messages[this.modes.HINTS] = "HINTS";
mode_messages[this.modes.ESCAPE_ONE_KEY] = "escape one key";
mode_messages[this.modes.ESCAPE_ALL_KEYS] = "escape all keys";
mode_messages[this.modes.ESCAPE_ONE_KEY | this.modes.ESCAPE_ALL_KEYS] = "pass one key";
mode_messages[this.modes.QUICK_HINT] = "quick";
mode_messages[this.modes.EXTENDED_HINT] = "extended";
mode_messages[this.modes.ALWAYS_HINT] = "always";
var callbacks = new Array(); var callbacks = new Array();
var mode = this.modes.NORMAL;
var extended_mode = this.modes.NONE;
var count = -1;
var inputbuffer = "";
function showMode()
{
if (!get_pref("showmode"))
return;
var str_mode = mode_messages[mode];
var str_extended = mode_messages[extended_mode];
if(!str_mode && !str_extended)
{
vimperator.echo("");
return;
}
if(str_mode && str_extended)
str_extended = " (" + str_extended + ")";
else
{
str_extended = "(" + str_extended + ")";
str_mode = "";
}
vimperator.echo("-- " + str_mode + str_extended + " --");
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
////////////////////// PUBLIC SECTION ////////////////////////////////////////// ////////////////////// PUBLIC SECTION //////////////////////////////////////////
@@ -1009,18 +778,304 @@ function Vimperator()
{ {
for (i in callbacks) for (i in callbacks)
{ {
[typ, mode, func] = callbacks[i]; [thistype, thismode, thisfunc] = callbacks[i];
if (hasMode(mode) && type == typ) if (vimperator.hasMode(thismode) && type == thistype)
return func.call(this, data); return thisfunc.call(this, data);
} }
return false; return false;
} }
this.foo = function () {alert("foo");};
// just forward these echo commands // just forward these echo commands
this.echo = this.commandline.echo; this.echo = this.commandline.echo;
this.echoerr = this.commandline.echoErr; this.echoerr = this.commandline.echoErr;
// set current mode
// use "null" if you only want to set one of those modes
this.setMode = function(main, extended, silent)
{
// if a main mode is set, the extended is always cleared
if (main)
{
mode = main;
extended_mode = this.modes.NONE;
}
if (typeof(extended) === "number")
extended_mode = extended;
if (typeof(silent) == "undefined" || !silent)
showMode();
}
// returns true if "whichmode" is found in either the main or
// extended mode
this.hasMode = function(whichmode)
{
return ((mode & whichmode) || (extended_mode & whichmode) > 0) ? true : false;
}
this.addMode = function(main, extended)
{
if (main)
mode |= main;
if (extended)
extended_mode |= extended;
showMode();
}
// always show the new mode in the statusline
this.removeMode = function(main, extended)
{
if (main)
mode = (mode | main) ^ main;
if (extended)
extended_mode = (extended_mode | extended) ^ extended;
showMode();
}
/* After pressing Escape, put focus on a non-input field of the browser document */
this.focusContent = function()
{
// count = -1;
// inputbuffer = "";
var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"].getService(Components.interfaces.nsIWindowWatcher);
if (window == ww.activeWindow && document.commandDispatcher.focusedElement)
document.commandDispatcher.focusedElement.blur();
content.focus();
//this.setMode(vimperator.modes.NORMAL);
//showMode();
}
this.onEvent = function(event)/*{{{*/
{
if (event.type != "keypress")
return false;
// change the event to a usable string representation
var key = keyToString(event);
//alert(key);
if (key == null)
return false;
if(event.type == "keydown")
{
logObject(event);
logObject(event.target);
return;//alert(event.target.id);
}
// sometimes the non-content area has focus, making our keys not work
// if (event.target.id == "main-window")
// alert("focusContent();");
// 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
if (isFormElemFocused())
return false;
// handle Escape-one-key mode (Ctrl-v)
if (vimperator.hasMode(vimperator.modes.ESCAPE_ONE_KEY) && !vimperator.hasMode(vimperator.modes.ESCAPE_ALL_KEYS))
{
vimperator.removeMode(null, vimperator.modes.ESCAPE_ONE_KEY);
return false;
}
// handle Escape-all-keys mode (I)
if (vimperator.hasMode(vimperator.modes.ESCAPE_ALL_KEYS))
{
if(vimperator.hasMode(vimperator.modes.ESCAPE_ONE_KEY))
vimperator.removeMode(null, vimperator.modes.ESCAPE_ONE_KEY); // and then let flow continue
else if (key == "<Esc>" || key == "<C-[>" || key == "<C-v>")
; // let flow continue to handle these keys
else
return false;
}
// // FIXME: handle middle click in content area {{{
// // alert(event.target.id);
// if (/*event.type == 'mousedown' && */event.button == 1 && event.target.id == 'content')
// {
// //echo("foo " + event.target.id);
// //if (document.commandDispatcher.focusedElement == command_line.inputField)
// {
// //alert(command_line.value.substring(0, command_line.selectionStart));
// command_line.value = command_line.value.substring(0, command_line.selectionStart) +
// readFromClipboard() +
// command_line.value.substring(command_line.selectionEnd, command_line.value.length);
// alert(command_line.value);
// }
// //else
// // {
// // openURLs(readFromClipboard());
// // }
// return true;
// } }}}
// if Hit-a-hint mode is on, special handling of keys is required
// g_hint_mappings is used
// FIXME: total mess
//if (hah.hintsVisible())
if (vimperator.hasMode(vimperator.modes.HINTS))
{
// never propagate this key to firefox, when hints are visible
event.preventDefault();
event.stopPropagation();
for (i = 0; i < g_hint_mappings.length; i++)
{
if(g_hint_mappings[i][0] == key)
{
if(g_hint_mappings[i][3] == true || hah.currentState() == 1)
{
//g_hint_mappings[i][1].call(this, event);
eval(g_hint_mappings[i][1]);
if (g_hint_mappings[i][2] == true) // stop processing this event
{
hah.disableHahMode();
g_inputbuffer = "";
vimperator.statusline.updateInputBuffer("");
return false;
}
else
{
// FIXME: make sure that YOU update the statusbar message yourself
// first in g_hint_mappings when in this mode!
vimperator.statusline.updateInputBuffer(g_inputbuffer);
return false;
}
}
}
}
// no mapping found, beep()
if (hah.currentState() == 1)
{
beep();
hah.disableHahMode();
g_inputbuffer = "";
vimperator.statusline.updateInputBuffer(g_inputbuffer);
return true;
}
// if we came here, let hit-a-hint process the key as it is part
// of a partial link
var res = hah.processEvent(event);
if (res < 0) // error occured processing this key
{
beep();
//if(hah.currentMode() == HINT_MODE_QUICK)
if(vimperator.hasMode(vimperator.modes.QUICK_HINT))
hah.disableHahMode();
else // ALWAYS mode
hah.resetHintedElements();
g_inputbuffer = "";
}
//else if (res == 0 || hah.currentMode() == HINT_MODE_EXTENDED) // key processed, part of a larger hint
else if (res == 0 || vimperator.hasMode(vimperator.modes.EXTENDED_HINT)) // key processed, part of a larger hint
g_inputbuffer += key;
else // this key completed a quick hint
{
// if the hint is all in UPPERCASE, open it in new tab
g_inputbuffer += key;
if (g_inputbuffer.toUpperCase() == g_inputbuffer)
hah.openHints(true, false);
else // open in current window
hah.openHints(false, false);
//if(hah.currentMode() == HINT_MODE_QUICK)
if(vimperator.hasMode(vimperator.modes.QUICK_HINT))
hah.disableHahMode();
else // ALWAYS mode
hah.resetHintedElements();
g_inputbuffer = "";
}
vimperator.statusline.updateInputBuffer(g_inputbuffer);
return true;
}
// set this variable to true, if we have the start of a mapping
var couldBecomeCompleteMapping = false;
var count_str = g_inputbuffer.match(/^[0-9]*/)[0];
// counts must be at the start of a complete mapping (10j -> go 10 lines down)
if (event.charCode >= 48 && event.charCode <= 57 && !(event.ctrlKey || event.altKey))
{
if (g_inputbuffer.search(/[^0-9]/) != -1)
{
g_inputbuffer = "";
beep();
vimperator.statusline.updateInputBuffer(g_inputbuffer);
return true;
}
else
{
// handle '0' specially to allow binding of 0
if (g_inputbuffer != "" || key != "0")
{
g_inputbuffer += key;
vimperator.statusline.updateInputBuffer(g_inputbuffer);
return true;
}
// else let the flow continue, and check if 0 is a mapping
}
}
for (var i in g_mappings)
{
// each internal mapping can have multiple keys
for (var j in g_mappings[i][COMMANDS])
{
var mapping = g_mappings[i][COMMANDS][j];
// alert("key: " + key +" - mapping: "+ mapping + " - g_input: " + g_inputbuffer);
if(count_str + mapping == g_inputbuffer + key)
//if (count_str + mapping == vimperator.commandline.getCommand() + key)
{
g_count = parseInt(count_str, 10);
if (isNaN(g_count))
g_count = -1;
// allow null (= no operation) mappings
if(g_mappings[i][FUNCTION] != null)
g_mappings[i][FUNCTION].call(this, g_count);
// command executed, reset input buffer
g_inputbuffer = "";
vimperator.statusline.updateInputBuffer(g_inputbuffer);
event.preventDefault();
event.stopPropagation();
return false;
}
else if ((count_str+mapping).indexOf(g_inputbuffer + key) == 0)
//else if ((count_str+mapping).indexOf(vimperator.commandline.getCommand() + key) == 0)
{
couldBecomeCompleteMapping = true;
}
}
}
if (couldBecomeCompleteMapping)
{
g_inputbuffer += key;
event.preventDefault();
event.stopPropagation();
}
else
{
g_inputbuffer = "";
beep();
}
vimperator.statusline.updateInputBuffer(g_inputbuffer);
return false;
}/*}}}*/
// alert('end');
} }
// provides functions for working with tabs // provides functions for working with tabs