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

use the singleton construction idiom for all top level modules and convert all

identifiers to camel case
This commit is contained in:
Doug Kearns
2007-11-22 11:30:12 +00:00
parent 2efad6186e
commit d5c5869d56
16 changed files with 4295 additions and 4204 deletions

2
NEWS
View File

@@ -53,7 +53,7 @@
* added a visual bell and replaced 'beep' with 'visualbell' * added a visual bell and replaced 'beep' with 'visualbell'
* added vimperator logo (can be seen in the addons manager) * added vimperator logo (can be seen in the addons manager)
* added 'hlsearch','incsearch', 'ignorecase' and 'smartcase' options * added 'hlsearch','incsearch', 'ignorecase' and 'smartcase' options
* many small bug fixes and enhancments * many small bug fixes and enhancements
2007-09-03: 2007-09-03:
* version 0.5.1 * version 0.5.1

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -26,14 +26,18 @@ the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL. the terms of any one of the MPL, the GPL or the LGPL.
}}} ***** END LICENSE BLOCK *****/ }}} ***** END LICENSE BLOCK *****/
vimperator.Completion = function () // {{{ vimperator.Completion = function () //{{{
{ {
// The completion substrings, used for showing the longest common match ////////////////////////////////////////////////////////////////////////////////
var g_substrings = []; ////////////////////// PRIVATE SECTION /////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
// the completion substrings, used for showing the longest common match
var substrings = [];
// function uses smartcase // function uses smartcase
// list = [ [['com1', 'com2'], 'text'], [['com3', 'com4'], 'text'] ] // list = [ [['com1', 'com2'], 'text'], [['com3', 'com4'], 'text'] ]
function build_longest_common_substring(list, filter) //{{{ function buildLongestCommonSubstring(list, filter)
{ {
var filtered = []; var filtered = [];
var ignorecase = false; var ignorecase = false;
@@ -51,19 +55,19 @@ vimperator.Completion = function () // {{{
if (item.indexOf(filter) == -1) if (item.indexOf(filter) == -1)
continue; continue;
if (g_substrings.length == 0) if (substrings.length == 0)
{ {
var last_index = item.lastIndexOf(filter); var lastIndex = item.lastIndexOf(filter);
var length = item.length; var length = item.length;
for (var k = item.indexOf(filter); k != -1 && k <= last_index; k = item.indexOf(filter, k + 1)) for (var k = item.indexOf(filter); k != -1 && k <= lastIndex; k = item.indexOf(filter, k + 1))
{ {
for (var l = k + filter.length; l <= length; l++) for (var l = k + filter.length; l <= length; l++)
g_substrings.push(list[i][0][j].substring(k, l)); substrings.push(list[i][0][j].substring(k, l));
} }
} }
else else
{ {
g_substrings = g_substrings.filter(function ($_) { substrings = substrings.filter(function ($_) {
return list[i][0][j].indexOf($_) >= 0; return list[i][0][j].indexOf($_) >= 0;
}); });
} }
@@ -72,10 +76,10 @@ vimperator.Completion = function () // {{{
} }
} }
return filtered; return filtered;
} //}}} }
/* this function is case sensitive and should be documented about input and output ;) */ // this function is case sensitive and should be documented about input and output ;)
function build_longest_starting_substring(list, filter) //{{{ function buildLongestStartingSubstring(list, filter)
{ {
var filtered = []; var filtered = [];
for (var i = 0; i < list.length; i++) for (var i = 0; i < list.length; i++)
@@ -85,15 +89,15 @@ vimperator.Completion = function () // {{{
if (list[i][0][j].indexOf(filter) != 0) if (list[i][0][j].indexOf(filter) != 0)
continue; continue;
if (g_substrings.length == 0) if (substrings.length == 0)
{ {
var length = list[i][0][j].length; var length = list[i][0][j].length;
for (var k = filter.length; k <= length; k++) for (var k = filter.length; k <= length; k++)
g_substrings.push(list[i][0][j].substring(0, k)); substrings.push(list[i][0][j].substring(0, k));
} }
else else
{ {
g_substrings = g_substrings.filter(function ($_) { substrings = substrings.filter(function ($_) {
return list[i][0][j].indexOf($_) == 0; return list[i][0][j].indexOf($_) == 0;
}); });
} }
@@ -102,18 +106,18 @@ vimperator.Completion = function () // {{{
} }
} }
return filtered; return filtered;
} //}}} }
/* discard all entries in the 'urls' array, which don't match 'filter */ /* discard all entries in the 'urls' array, which don't match 'filter */
function filter_url_array(urls, filter) //{{{ function filterUrlArray(urls, filter)
{ {
var filtered = []; var filtered = [];
// completions which don't match the url but just the description // completions which don't match the url but just the description
// list them add the end of the array // list them add the end of the array
var additional_completions = []; var additionalCompletions = [];
if (!filter) return urls.map(function ($_) { if (!filter) return urls.map(function ($_) {
return [$_[0], $_[1]] return [$_[0], $_[1]];
}); });
var ignorecase = false; var ignorecase = false;
@@ -122,7 +126,7 @@ vimperator.Completion = function () // {{{
/* /*
* Longest Common Subsequence * Longest Common Subsequence
* This shouldn't use build_longest_common_substring * This shouldn't use buildLongestCommonSubstring
* for performance reasons, so as not to cycle through the urls twice * for performance reasons, so as not to cycle through the urls twice
*/ */
for (var i = 0; i < urls.length; i++) for (var i = 0; i < urls.length; i++)
@@ -138,49 +142,54 @@ vimperator.Completion = function () // {{{
if (url.indexOf(filter) == -1) if (url.indexOf(filter) == -1)
{ {
if (title.indexOf(filter) != -1) if (title.indexOf(filter) != -1)
additional_completions.push([ urls[i][0], urls[i][1] ]); additionalCompletions.push([ urls[i][0], urls[i][1] ]);
continue; continue;
} }
if (g_substrings.length == 0) // Build the substrings if (substrings.length == 0) // Build the substrings
{ {
var last_index = url.lastIndexOf(filter); var lastIndex = url.lastIndexOf(filter);
var url_length = url.length; var urlLength = url.length;
for (var k = url.indexOf(filter); k != -1 && k <= last_index; k = url.indexOf(filter, k + 1)) for (var k = url.indexOf(filter); k != -1 && k <= lastIndex; k = url.indexOf(filter, k + 1))
{ {
for (var l = k + filter.length; l <= url_length; l++) for (var l = k + filter.length; l <= urlLength; l++)
g_substrings.push(url.substring(k, l)); substrings.push(url.substring(k, l));
} }
} }
else else
{ {
g_substrings = g_substrings.filter(function ($_) { substrings = substrings.filter(function ($_) {
return url.indexOf($_) >= 0; return url.indexOf($_) >= 0;
}); });
} }
filtered.push([urls[i][0], urls[i][1]]); filtered.push([urls[i][0], urls[i][1]]);
} }
return filtered.concat(additional_completions); return filtered.concat(additionalCompletions);
} //}}} }
/////////////////////////////////////////////////////////////////////////////}}}
////////////////////// PUBLIC SECTION //////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
return { return {
/* /*
* returns the longest common substring * returns the longest common substring
* used for the 'longest' setting for wildmode * used for the 'longest' setting for wildmode
*/ */
get_longest_substring: function () //{{{ getLongestSubstring: function ()
{ {
if (g_substrings.length == 0) if (substrings.length == 0)
return ""; return "";
var longest = g_substrings[0]; var longest = substrings[0];
for (var i = 1; i < g_substrings.length; i++) for (var i = 1; i < substrings.length; i++)
{ {
if (g_substrings[i].length > longest.length) if (substrings[i].length > longest.length)
longest = g_substrings[i]; longest = substrings[i];
} }
return longest; return longest;
}, //}}} },
/* /*
* filter a list of urls * filter a list of urls
@@ -189,29 +198,29 @@ vimperator.Completion = function () // {{{
* depending on the 'complete' option * depending on the 'complete' option
* if the 'complete' argument is passed like "h", it temporarily overrides the complete option * if the 'complete' argument is passed like "h", it temporarily overrides the complete option
*/ */
get_url_completions: function (filter, complete) //{{{ url: function (filter, complete)
{ {
var completions = []; var completions = [];
g_substrings = []; substrings = [];
var cpt = complete || vimperator.options["complete"]; var cpt = complete || vimperator.options["complete"];
// join all completion arrays together // join all completion arrays together
for (var i = 0; i < cpt.length; i++) for (var i = 0; i < cpt.length; i++)
{ {
if (cpt[i] == "s") if (cpt[i] == "s")
completions = completions.concat(this.get_search_completions(filter)); completions = completions.concat(this.search(filter));
else if (cpt[i] == "b") else if (cpt[i] == "b")
completions = completions.concat(this.get_bookmark_completions(filter)); completions = completions.concat(this.bookmark(filter));
else if (cpt[i] == "h") else if (cpt[i] == "h")
completions = completions.concat(this.get_history_completions(filter)); completions = completions.concat(this.history(filter));
else if (cpt[i] == "f") else if (cpt[i] == "f")
completions = completions.concat(this.get_file_completions(filter, true)); completions = completions.concat(this.file(filter, true));
} }
return completions; return completions;
}, //}}} },
get_search_completions: function (filter) //{{{ search: function (filter)
{ {
var engines = vimperator.bookmarks.getSearchEngines().concat(vimperator.bookmarks.getKeywords()); var engines = vimperator.bookmarks.getSearchEngines().concat(vimperator.bookmarks.getKeywords());
@@ -221,28 +230,28 @@ vimperator.Completion = function () // {{{
var mapped = engines.map(function (engine) { var mapped = engines.map(function (engine) {
return [[engine[0]], engine[1]]; return [[engine[0]], engine[1]];
}); });
return build_longest_common_substring(mapped, filter); return buildLongestCommonSubstring(mapped, filter);
}, //}}} },
get_history_completions: function (filter) //{{{ history: function (filter)
{ {
var items = vimperator.history.get(); var items = vimperator.history.get();
return filter_url_array(items, filter); return filterUrlArray(items, filter);
}, //}}} },
get_bookmark_completions: function (filter) //{{{ bookmark: function (filter)
{ {
var bookmarks = vimperator.bookmarks.get(); var bookmarks = vimperator.bookmarks.get();
return filter_url_array(bookmarks, filter); return filterUrlArray(bookmarks, filter);
}, //}}} },
// TODO: support file:// and \ or / path separators on both platforms // TODO: support file:// and \ or / path separators on both platforms
get_file_completions: function (filter) file: function (filter)
{ {
// this is now also used as part of the url completion, so the // this is now also used as part of the url completion, so the
// substrings shouldn't be cleared for that case // substrings shouldn't be cleared for that case
if (!arguments[1]) if (!arguments[1])
g_substrings = []; substrings = [];
var matches = filter.match(/^(.*[\/\\])(.*?)$/); var matches = filter.match(/^(.*[\/\\])(.*?)$/);
var dir; var dir;
@@ -266,56 +275,56 @@ vimperator.Completion = function () // {{{
} }
return build_longest_starting_substring(mapped, filter); return buildLongestStartingSubstring(mapped, filter);
}, },
get_help_completions: function (filter) //{{{ help: function (filter)
{ {
var help_array = [[["introduction"], "Introductory text"], var helpArray = [[["introduction"], "Introductory text"],
[["initialization"], "Initialization and startup"], [["initialization"], "Initialization and startup"],
[["mappings"], "Normal mode commands"], [["mappings"], "Normal mode commands"],
[["commands"], "Ex commands"], [["commands"], "Ex commands"],
[["options"], "Configuration options"]]; // TODO: hardcoded until we have proper 'pages' [["options"], "Configuration options"]]; // TODO: hardcoded until we have proper 'pages'
g_substrings = []; substrings = [];
for (var command in vimperator.commands) for (var command in vimperator.commands)
help_array.push([command.long_names.map(function ($_) { return ":" + $_; }), command.short_help]); helpArray.push([command.longNames.map(function ($_) { return ":" + $_; }), command.shortHelp]);
options = this.get_options_completions(filter, true); options = this.option(filter, true);
help_array = help_array.concat(options.map(function ($_) { helpArray = helpArray.concat(options.map(function ($_) {
return [ return [
$_[0].map(function ($_) { return "'" + $_ + "'"; }), $_[0].map(function ($_) { return "'" + $_ + "'"; }),
$_[1] $_[1]
]; ];
})); }));
for (var map in vimperator.mappings) for (var map in vimperator.mappings)
help_array.push([map.names, map.short_help]); helpArray.push([map.names, map.shortHelp]);
if (!filter) return help_array.map(function ($_) { if (!filter) return helpArray.map(function ($_) {
return [$_[0][0], $_[1]]; // unfiltered, use the first command return [$_[0][0], $_[1]]; // unfiltered, use the first command
}); });
return build_longest_common_substring(help_array, filter); return buildLongestCommonSubstring(helpArray, filter);
}, //}}} },
get_command_completions: function (filter) //{{{ command: function (filter)
{ {
g_substrings = []; substrings = [];
var completions = []; var completions = [];
if (!filter) if (!filter)
{ {
for (var command in vimperator.commands) for (var command in vimperator.commands)
completions.push([command.name, command.short_help]); completions.push([command.name, command.shortHelp]);
return completions; return completions;
} }
for (var command in vimperator.commands) for (var command in vimperator.commands)
completions.push([command.long_names, command.short_help]); completions.push([command.longNames, command.shortHelp]);
return build_longest_starting_substring(completions, filter); return buildLongestStartingSubstring(completions, filter);
}, //}}} },
get_options_completions: function (filter, unfiltered) //{{{ option: function (filter, unfiltered)
{ {
g_substrings = []; substrings = [];
var options_completions = []; var optionsCompletions = [];
var prefix = filter.match(/^no|inv/) || ""; var prefix = filter.match(/^no|inv/) || "";
if (prefix) if (prefix)
@@ -328,7 +337,7 @@ vimperator.Completion = function () // {{{
{ {
if (prefix && option.type != "boolean") if (prefix && option.type != "boolean")
continue; continue;
options.push([option.names, option.short_help]); options.push([option.names, option.shortHelp]);
} }
return options; return options;
} }
@@ -340,7 +349,7 @@ vimperator.Completion = function () // {{{
{ {
if (prefix && option.type != "boolean") if (prefix && option.type != "boolean")
continue; continue;
options.push([prefix + option.name, option.short_help]); options.push([prefix + option.name, option.shortHelp]);
} }
return options; return options;
} }
@@ -352,15 +361,15 @@ vimperator.Completion = function () // {{{
{ {
if (option.hasName(filter)) if (option.hasName(filter))
{ {
options_completions.push([filter + "=" + option.value, ""]); optionsCompletions.push([filter + "=" + option.value, ""]);
return options_completions; return optionsCompletions;
} }
} }
return options_completions; return optionsCompletions;
} }
// can't use b_l_s_s, since this has special requirements (the prefix) // can't use b_l_s_s, since this has special requirements (the prefix)
var filter_length = filter.length; var filterLength = filter.length;
for (var option in vimperator.options) for (var option in vimperator.options)
{ {
if (prefix && option.type != "boolean") if (prefix && option.type != "boolean")
@@ -371,29 +380,29 @@ vimperator.Completion = function () // {{{
if (option.names[j].indexOf(filter) != 0) if (option.names[j].indexOf(filter) != 0)
continue; continue;
if (g_substrings.length == 0) if (substrings.length == 0)
{ {
var length = option.names[j].length; var length = option.names[j].length;
for (var k = filter_length; k <= length; k++) for (var k = filterLength; k <= length; k++)
g_substrings.push(prefix + option.names[j].substring(0, k)); substrings.push(prefix + option.names[j].substring(0, k));
} }
else else
{ {
g_substrings = g_substrings.filter(function ($_) { substrings = substrings.filter(function ($_) {
return option.names[j].indexOf($_) == 0; return option.names[j].indexOf($_) == 0;
}); });
} }
options_completions.push([prefix + option.names[j], option.short_help]); optionsCompletions.push([prefix + option.names[j], option.shortHelp]);
break; break;
} }
} }
return options_completions; return optionsCompletions;
}, //}}} },
get_buffer_completions: function (filter) //{{{ buffer: function (filter)
{ {
g_substrings = []; substrings = [];
var items = []; var items = [];
var num = getBrowser().browsers.length; var num = getBrowser().browsers.length;
var title, url; var title, url;
@@ -424,13 +433,13 @@ vimperator.Completion = function () // {{{
if (!filter) return items.map(function ($_) { if (!filter) return items.map(function ($_) {
return [$_[0][0], $_[1]]; return [$_[0][0], $_[1]];
}); });
return build_longest_common_substring(items, filter); return buildLongestCommonSubstring(items, filter);
}, //}}} },
get_sidebar_completions: function (filter) //{{{ sidebar: function (filter)
{ {
g_substrings = []; substrings = [];
var menu = document.getElementById("viewSidebarMenu") var menu = document.getElementById("viewSidebarMenu");
var nodes = []; var nodes = [];
for (var i = 0; i < menu.childNodes.length; i++) for (var i = 0; i < menu.childNodes.length; i++)
@@ -443,12 +452,12 @@ vimperator.Completion = function () // {{{
return [[node[0]], node[1]]; return [[node[0]], node[1]];
}); });
return build_longest_common_substring(mapped, filter); return buildLongestCommonSubstring(mapped, filter);
}, //}}} },
javascript: function (str) // {{{ javascript: function (str) // {{{
{ {
g_substrings = []; substrings = [];
var matches = str.match(/^(.*?)(\s*\.\s*)?(\w*)$/); var matches = str.match(/^(.*?)(\s*\.\s*)?(\w*)$/);
var object = "window"; var object = "window";
var filter = matches[3] || ""; var filter = matches[3] || "";
@@ -514,18 +523,18 @@ vimperator.Completion = function () // {{{
completions = []; completions = [];
} }
return build_longest_starting_substring(completions, filter); return buildLongestStartingSubstring(completions, filter);
}, // }}} }, // }}}
// helper function which checks if the given arguments pass "filter" // helper function which checks if the given arguments pass "filter"
// items must be an array of strings // items must be an array of strings
// if case_sensitive == true, be sure to pass filter already in lowercased version // if caseSensitive == true, be sure to pass filter already in lowercased version
match: function (filter, items, case_sensitive) match: function (filter, items, caseSensitive)
{ {
if (typeof(filter) != "string" || !items) if (typeof filter != "string" || !items)
return false; return false;
if (case_sensitive) if (caseSensitive)
{ {
for (var i = 0; i < items.length; i++) for (var i = 0; i < items.length; i++)
{ {
@@ -544,7 +553,7 @@ vimperator.Completion = function () // {{{
return false; return false;
}, },
exTabCompletion: function (str) //{{{ exTabCompletion: function (str)
{ {
var [count, cmd, special, args] = vimperator.commands.parseCommand(str); var [count, cmd, special, args] = vimperator.commands.parseCommand(str);
var completions = []; var completions = [];
@@ -555,7 +564,7 @@ vimperator.Completion = function () // {{{
var matches = str.match(/^(:*\d*)\w*$/); var matches = str.match(/^(:*\d*)\w*$/);
if (matches) if (matches)
{ {
completions = this.get_command_completions(cmd); completions = this.command(cmd);
start = matches[1].length; start = matches[1].length;
} }
else // dynamically get completions as specified with the command's completer function else // dynamically get completions as specified with the command's completer function
@@ -587,9 +596,10 @@ vimperator.Completion = function () // {{{
} }
} }
return [start, completions]; return [start, completions];
} //}}} }
} };
} // }}} //}}}
}; //}}}
// vim: set fdm=marker sw=4 ts=4 et: // vim: set fdm=marker sw=4 ts=4 et:

File diff suppressed because it is too large Load Diff

View File

@@ -39,27 +39,32 @@ the terms of any one of the MPL, the GPL or the LGPL.
// make sure you only create this object when the "vimperator" object is ready // make sure you only create this object when the "vimperator" object is ready
vimperator.Search = function () //{{{ vimperator.Search = function () //{{{
{ {
var self = this; // needed for callbacks since "this" is the "vimperator" object in a callback ////////////////////////////////////////////////////////////////////////////////
var found = false; // true if the last search was successful ////////////////////// PRIVATE SECTION /////////////////////////////////////////
var backwards = false; // currently searching backwards /////////////////////////////////////////////////////////////////////////////{{{
var search_string = ""; // current search string (without modifiers)
var search_pattern = ""; // current search string (includes modifiers) // FIXME:
var last_search_pattern = ""; // the last searched pattern (includes modifiers) //var self = this; // needed for callbacks since "this" is the "vimperator" object in a callback
var last_search_string = ""; // the last searched string (without modifiers) var found = false; // true if the last search was successful
var last_search_backwards = false; // like "backwards", but for the last search, so if you cancel a search with <esc> this is not set var backwards = false; // currently searching backwards
var case_sensitive = false; // search string is case sensitive var searchString = ""; // current search string (without modifiers)
var links_only = false; // search is limited to link text only var searchPattern = ""; // current search string (includes modifiers)
var lastSearchPattern = ""; // the last searched pattern (includes modifiers)
var lastSearchString = ""; // the last searched string (without modifiers)
var lastSearchBackwards = false; // like "backwards", but for the last search, so if you cancel a search with <esc> this is not set
var caseSensitive = false; // search string is case sensitive
var linksOnly = false; // search is limited to link text only
// Event handlers for search - closure is needed // Event handlers for search - closure is needed
vimperator.registerCallback("change", vimperator.modes.SEARCH_FORWARD, function (command) { self.searchKeyPressed(command); }); vimperator.registerCallback("change", vimperator.modes.SEARCH_FORWARD, function (command) { vimperator.search.searchKeyPressed(command); });
vimperator.registerCallback("submit", vimperator.modes.SEARCH_FORWARD, function (command) { self.searchSubmitted(command); }); vimperator.registerCallback("submit", vimperator.modes.SEARCH_FORWARD, function (command) { vimperator.search.searchSubmitted(command); });
vimperator.registerCallback("cancel", vimperator.modes.SEARCH_FORWARD, function () { self.searchCanceled(); }); vimperator.registerCallback("cancel", vimperator.modes.SEARCH_FORWARD, function () { vimperator.search.searchCanceled(); });
// TODO: allow advanced modes in register/triggerCallback // TODO: allow advanced modes in register/triggerCallback
vimperator.registerCallback("change", vimperator.modes.SEARCH_BACKWARD, function (command) { self.searchKeyPressed(command); }); vimperator.registerCallback("change", vimperator.modes.SEARCH_BACKWARD, function (command) { vimperator.search.searchKeyPressed(command); });
vimperator.registerCallback("submit", vimperator.modes.SEARCH_BACKWARD, function (command) { self.searchSubmitted(command); }); vimperator.registerCallback("submit", vimperator.modes.SEARCH_BACKWARD, function (command) { vimperator.search.searchSubmitted(command); });
vimperator.registerCallback("cancel", vimperator.modes.SEARCH_BACKWARD, function () { self.searchCanceled(); }); vimperator.registerCallback("cancel", vimperator.modes.SEARCH_BACKWARD, function () { vimperator.search.searchCanceled(); });
// set search_string, search_pattern, case_sensitive, links_only // set searchString, searchPattern, caseSensitive, linksOnly
function processUserPattern(pattern) function processUserPattern(pattern)
{ {
// strip off pattern terminator and offset // strip off pattern terminator and offset
@@ -68,32 +73,32 @@ vimperator.Search = function () //{{{
else else
pattern = pattern.replace(/\/.*/, ""); pattern = pattern.replace(/\/.*/, "");
search_pattern = pattern; searchPattern = pattern;
// links only search - \l wins if both modifiers specified // links only search - \l wins if both modifiers specified
if (/\\l/.test(pattern)) if (/\\l/.test(pattern))
links_only = false; linksOnly = false;
else if (/\L/.test(pattern)) else if (/\L/.test(pattern))
links_only = true; linksOnly = true;
else if (vimperator.options["linksearch"]) else if (vimperator.options["linksearch"])
links_only = true; linksOnly = true;
else else
links_only = false; linksOnly = false;
// strip links-only modifiers // strip links-only modifiers
pattern = pattern.replace(/(\\)?\\[lL]/g, function ($0, $1) { return $1 ? $0 : ""; }); pattern = pattern.replace(/(\\)?\\[lL]/g, function ($0, $1) { return $1 ? $0 : ""; });
// case sensitivity - \c wins if both modifiers specified // case sensitivity - \c wins if both modifiers specified
if (/\c/.test(pattern)) if (/\c/.test(pattern))
case_sensitive = false; caseSensitive = false;
else if (/\C/.test(pattern)) else if (/\C/.test(pattern))
case_sensitive = true; caseSensitive = true;
else if (vimperator.options["ignorecase"] && vimperator.options["smartcase"] && /[A-Z]/.test(pattern)) else if (vimperator.options["ignorecase"] && vimperator.options["smartcase"] && /[A-Z]/.test(pattern))
case_sensitive = true; caseSensitive = true;
else if (vimperator.options["ignorecase"]) else if (vimperator.options["ignorecase"])
case_sensitive = false; caseSensitive = false;
else else
case_sensitive = true; caseSensitive = true;
// strip case-sensitive modifiers // strip case-sensitive modifiers
pattern = pattern.replace(/(\\)?\\[cC]/g, function ($0, $1) { return $1 ? $0 : ""; }); pattern = pattern.replace(/(\\)?\\[cC]/g, function ($0, $1) { return $1 ? $0 : ""; });
@@ -101,171 +106,179 @@ vimperator.Search = function () //{{{
// remove any modifer escape \ // remove any modifer escape \
pattern = pattern.replace(/\\(\\[cClL])/g, "$1"); pattern = pattern.replace(/\\(\\[cClL])/g, "$1");
search_string = pattern; searchString = pattern;
} }
// Called when the search dialog is asked for /////////////////////////////////////////////////////////////////////////////}}}
// If you omit "mode", it will default to forward searching ////////////////////// PUBLIC SECTION //////////////////////////////////////////
this.openSearchDialog = function (mode) /////////////////////////////////////////////////////////////////////////////{{{
{
if (mode == vimperator.modes.SEARCH_BACKWARD) return {
// Called when the search dialog is asked for
// If you omit "mode", it will default to forward searching
openSearchDialog: function (mode)
{ {
vimperator.commandline.open("?", "", vimperator.modes.SEARCH_BACKWARD); if (mode == vimperator.modes.SEARCH_BACKWARD)
backwards = true; {
} vimperator.commandline.open("?", "", vimperator.modes.SEARCH_BACKWARD);
else backwards = true;
}
else
{
vimperator.commandline.open("/", "", vimperator.modes.SEARCH_FORWARD);
backwards = false;
}
// TODO: focus the top of the currently visible screen
},
// Finds text in a page
// TODO: backwards seems impossible i fear :(
find: function (str, backwards)
{ {
vimperator.commandline.open("/", "", vimperator.modes.SEARCH_FORWARD); var fastFind = getBrowser().fastFind;
backwards = false;
}
// TODO: focus the top of the currently visible screen processUserPattern(str);
}
// Finds text in a page fastFind.caseSensitive = caseSensitive;
// TODO: backwards seems impossible i fear :( found = fastFind.find(searchString, linksOnly) != Components.interfaces.nsITypeAheadFind.FIND_NOTFOUND;
this.find = function (str, backwards)
{
var fastFind = getBrowser().fastFind;
processUserPattern(str); if (!found)
setTimeout(function () { vimperator.echoerr("E486: Pattern not found: " + searchPattern); }, 0);
fastFind.caseSensitive = case_sensitive; return found;
found = fastFind.find(search_string, links_only) != Components.interfaces.nsITypeAheadFind.FIND_NOTFOUND; },
if (!found) // Called when the current search needs to be repeated
setTimeout(function () { vimperator.echoerr("E486: Pattern not found: " + search_pattern); }, 0); findAgain: function (reverse)
return found;
}
// Called when the current search needs to be repeated
this.findAgain = function (reverse)
{
// this hack is needed to make n/N work with the correct string, if
// we typed /foo<esc> after the original search. Since searchString is
// readonly we have to call find() again to update it.
if (getBrowser().fastFind.searchString != last_search_string)
this.find(last_search_string, false);
var up = reverse ? !last_search_backwards : last_search_backwards;
var result;
if (up)
result = getBrowser().fastFind.findPrevious();
else
result = getBrowser().fastFind.findNext();
if (result == Components.interfaces.nsITypeAheadFind.FIND_NOTFOUND)
{ {
vimperator.echoerr("E486: Pattern not found: " + last_search_pattern); // this hack is needed to make n/N work with the correct string, if
} // we typed /foo<esc> after the original search. Since searchString is
else if (result == Components.interfaces.nsITypeAheadFind.FIND_WRAPPED) // readonly we have to call find() again to update it.
if (getBrowser().fastFind.searchString != lastSearchString)
this.find(lastSearchString, false);
var up = reverse ? !lastSearchBackwards : lastSearchBackwards;
var result;
if (up)
result = getBrowser().fastFind.findPrevious();
else
result = getBrowser().fastFind.findNext();
if (result == Components.interfaces.nsITypeAheadFind.FIND_NOTFOUND)
{
vimperator.echoerr("E486: Pattern not found: " + lastSearchPattern);
}
else if (result == Components.interfaces.nsITypeAheadFind.FIND_WRAPPED)
{
// hack needed, because wrapping causes a "scroll" event which clears
// our command line
setTimeout(function () {
if (up)
vimperator.commandline.echo("search hit TOP, continuing at BOTTOM", vimperator.commandline.HL_WARNING);
else
vimperator.commandline.echo("search hit BOTTOM, continuing at TOP", vimperator.commandline.HL_WARNING);
}, 0);
}
else
{
vimperator.echo((up ? "?" : "/") + lastSearchPattern);
if (vimperator.options["hlsearch"])
this.highlight(lastSearchString);
}
},
// Called when the user types a key in the search dialog. Triggers a find attempt if 'incsearch' is set
searchKeyPressed: function (command)
{ {
// hack needed, because wrapping causes a "scroll" event which clears if (vimperator.options["incsearch"])
// our command line this.find(command, backwards);
setTimeout(function () { },
if (up)
vimperator.commandline.echo("search hit TOP, continuing at BOTTOM", vimperator.commandline.HL_WARNING); // Called when the enter key is pressed to trigger a search
else // use forcedBackward if you call this function directly
vimperator.commandline.echo("search hit BOTTOM, continuing at TOP", vimperator.commandline.HL_WARNING); searchSubmitted: function (command, forcedBackward)
}, 0);
}
else
{ {
vimperator.echo((up ? "?" : "/") + last_search_pattern); if (typeof forcedBackward === "boolean")
backwards = forcedBackward;
// use the last pattern if none specified
if (!command)
command = lastSearchPattern;
this.clear();
this.find(command, backwards);
lastSearchBackwards = backwards;
lastSearchPattern = command.replace(backwards ? /\?.*/ : /\/.*/, ""); // XXX
lastSearchString = searchString;
// TODO: move to find() when reverse incremental searching is kludged in
// need to find again for reverse searching
if (backwards)
setTimeout(function () { vimperator.search.findAgain(false); }, 0);
if (vimperator.options["hlsearch"]) if (vimperator.options["hlsearch"])
this.highlight(last_search_string); this.highlight(searchString);
}
}
// Called when the user types a key in the search dialog. Triggers a find attempt if 'incsearch' is set vimperator.setMode(vimperator.modes.NORMAL);
this.searchKeyPressed = function (command) vimperator.focusContent();
{ },
if (vimperator.options["incsearch"])
this.find(command, backwards);
}
// Called when the enter key is pressed to trigger a search // Called when the search is cancelled - for example if someone presses
// use forced_direction if you call this function directly // escape while typing a search
this.searchSubmitted = function (command, forced_backward) searchCanceled: function ()
{
if (typeof forced_backward === "boolean")
backwards = forced_backward;
// use the last pattern if none specified
if (!command)
command = last_search_pattern;
this.clear();
this.find(command, backwards);
last_search_backwards = backwards;
last_search_pattern = command.replace(backwards ? /\?.*/ : /\/.*/, ""); // XXX
last_search_string = search_string;
// TODO: move to find() when reverse incremental searching is kludged in
// need to find again for reverse searching
if (backwards)
setTimeout(function () { self.findAgain(false); }, 0);
if (vimperator.options["hlsearch"])
this.highlight(search_string);
vimperator.setMode(vimperator.modes.NORMAL);
vimperator.focusContent();
}
// Called when the search is cancelled - for example if someone presses
// escape while typing a search
this.searchCanceled = function ()
{
//removeMode(MODE_SEARCH);
vimperator.setMode(vimperator.modes.NORMAL);
vimperator.focusContent();
}
this.highlight = function (text)
{
// already highlighted?
if (window.content.document.getElementById("__firefox-findbar-search-id"))
return;
if (!text)
text = last_search_string;
// NOTE: gFindBar.setCaseSensitivity() in FF2 does NOT set the
// accessibility.typeaheadfind.casesensitive pref as needed by
// highlightDoc()
gFindBar.mTypeAheadCaseSensitive = case_sensitive ? 1 : 0;
gFindBar.highlightDoc("white", "black", text);
// TODO: seems fast enough for now...just
// NOTE: FF2 highlighting spans all have the same id rather than a class attribute
(function (win)
{ {
for (var i = 0; i < win.frames.length; i++) //removeMode(MODE_SEARCH);
arguments.callee(win.frames[i]); vimperator.setMode(vimperator.modes.NORMAL);
var spans = vimperator.buffer.evaluateXPath("//span[@id='__firefox-findbar-search-id']", win.document); vimperator.focusContent();
for (var i = 0; i < spans.snapshotLength; i++) },
spans.snapshotItem(i).setAttribute("style", vimperator.options["hlsearchstyle"]);
})(window.content);
// recreate selection since _highlightDoc collapses the selection backwards highlight: function (text)
getBrowser().fastFind.findNext(); {
// already highlighted?
if (window.content.document.getElementById("__firefox-findbar-search-id"))
return;
// TODO: remove highlighting from non-link matches (HTML - A/AREA with href attribute; XML - Xlink [@type="simple"]) if (!text)
} text = lastSearchString;
this.clear = function () // NOTE: gFindBar.setCaseSensitivity() in FF2 does NOT set the
{ // accessibility.typeaheadfind.casesensitive pref as needed by
gFindBar.highlightDoc(); // highlightDoc()
// need to manually collapse the selection if the document is not gFindBar.mTypeAheadCaseSensitive = caseSensitive ? 1 : 0;
// highlighted gFindBar.highlightDoc("white", "black", text);
getBrowser().fastFind.collapseSelection();
}
} //}}} // TODO: seems fast enough for now...just
// NOTE: FF2 highlighting spans all have the same id rather than a class attribute
(function (win)
{
for (var i = 0; i < win.frames.length; i++)
arguments.callee(win.frames[i]);
var spans = vimperator.buffer.evaluateXPath("//span[@id='__firefox-findbar-search-id']", win.document);
for (var i = 0; i < spans.snapshotLength; i++)
spans.snapshotItem(i).setAttribute("style", vimperator.options["hlsearchstyle"]);
})(window.content);
// recreate selection since _highlightDoc collapses the selection backwards
getBrowser().fastFind.findNext();
// TODO: remove highlighting from non-link matches (HTML - A/AREA with href attribute; XML - Xlink [@type="simple"])
},
clear: function ()
{
gFindBar.highlightDoc();
// need to manually collapse the selection if the document is not
// highlighted
getBrowser().fastFind.collapseSelection();
}
};
//}}}
}; //}}}
// vim: set fdm=marker sw=4 ts=4 et: // vim: set fdm=marker sw=4 ts=4 et:

View File

@@ -52,7 +52,7 @@ vimperator.help = function (section, easter) //{{{
{ {
// the usage information for the command // the usage information for the command
ret += '<tr class="description"><td class="usage" valign="top">'; ret += '<tr class="description"><td class="usage" valign="top">';
for (var j=0; j < command.usage.length; j++) for (var j = 0; j < command.usage.length; j++)
{ {
var usage = command.usage[j]; var usage = command.usage[j];
@@ -72,10 +72,10 @@ vimperator.help = function (section, easter) //{{{
ret += '</td><td valign="top">'; ret += '</td><td valign="top">';
// the actual help text with the first line in bold // the actual help text with the first line in bold
if (command.short_help) if (command.shortHelp)
{ {
ret += '<span class="shorthelp">'; ret += '<span class="shorthelp">';
ret += command.short_help; // the help description ret += command.shortHelp; // the help description
ret += "</span><br/>"; ret += "</span><br/>";
if (func) // for options we print default values here, e.g. if (func) // for options we print default values here, e.g.
{ {
@@ -93,11 +93,11 @@ vimperator.help = function (section, easter) //{{{
// the tags which are printed on the top right // the tags which are printed on the top right
ret += '</td><td class="taglist" valign="top">'; ret += '</td><td class="taglist" valign="top">';
var names = command.names; var names = command.names;
for (var j=0; j < names.length; j++) for (var j = 0; j < names.length; j++)
{ {
var cmd_name = names[j]; var cmdName = names[j];
cmd_name = vimperator.util.escapeHTML(cmd_name); cmdName = vimperator.util.escapeHTML(cmdName);
ret += '<code class="tag">' + beg + cmd_name + end + '</code><br/>'; ret += '<code class="tag">' + beg + cmdName + end + '</code><br/>';
} }
ret += '</td></tr>'; ret += '</td></tr>';
@@ -114,17 +114,17 @@ vimperator.help = function (section, easter) //{{{
ret = command.type + ' (default: '; ret = command.type + ' (default: ';
if (command.type == "boolean") if (command.type == "boolean")
{ {
if (command.default_value == true) if (command.defaultValue == true)
ret += "on"; ret += "on";
else else
ret += "off"; ret += "off";
} }
else else
{ {
if (typeof command.default_value == "string" && command.default_value.length == 0) if (typeof command.defaultValue == "string" && command.defaultValue.length == 0)
ret += "''"; ret += "''";
else else
ret += command.default_value; ret += command.defaultValue;
} }
ret += ")<br/>"; ret += ")<br/>";
@@ -286,6 +286,6 @@ vimperator.help = function (section, easter) //{{{
window.content.scrollTo(0, pos[1]); window.content.scrollTo(0, pos[1]);
} }
}, 0); }, 0);
} //}}} }; //}}}
// vim: set fdm=marker sw=4 ts=4 et: // vim: set fdm=marker sw=4 ts=4 et:

View File

@@ -24,11 +24,11 @@
vimperator.Hints = function () //{{{ vimperator.Hints = function () //{{{
{ {
const HINT_PREFIX = "hah_hint_"; // prefix for the hint id ////////////////////////////////////////////////////////////////////////////////
////////////////////// PRIVATE SECTION /////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
this.hintedElements = function () { return hintedElems; }; const HINT_PREFIX = "hah_hint_"; // prefix for the hint id
this.currentState = function () { return state;};
this.setCurrentState = function (s) { state = s;};
var isHahModeEnabled = false; // is typing mode on var isHahModeEnabled = false; // is typing mode on
var hintedElems = []; var hintedElems = [];
@@ -68,27 +68,6 @@ vimperator.Hints = function () //{{{
win.coordLoaderId = window.setTimeout("vimperator.hints.loadCoord(" + win.winId + ", 0);", 1); win.coordLoaderId = window.setTimeout("vimperator.hints.loadCoord(" + win.winId + ", 0);", 1);
} }
this.loadCoord = function (winId, i)
{
win = wins[winId];
// win.res is not ready when loading has not finished yet
if (!win.res)
return;
var elem = win.res.snapshotItem(i);
if (elem)
genElemCoords(elem);
i++;
if (i < win.res.snapshotLength && !isHahModeEnabled)
window.setTimeout("vimperator.hints.loadCoord(" + winId + ", "+ i +");", 1);
else
win.coordLoaderId = null;
};
function genElemCoords(elem) function genElemCoords(elem)
{ {
// NOTE: experiment for making the function faster, report problems // NOTE: experiment for making the function faster, report problems
@@ -101,7 +80,7 @@ vimperator.Hints = function () //{{{
//} //}
//return; //return;
if (typeof(elem.validCoord) != "undefined") if (typeof elem.validCoord != "undefined")
{ {
if (elem.validCoord == elem.ownerDocument.validCoords) if (elem.validCoord == elem.ownerDocument.validCoords)
return; return;
@@ -157,7 +136,7 @@ vimperator.Hints = function () //{{{
if (!hintContainer) if (!hintContainer)
return false; return false;
} }
hintContainer.valid_hint_count = 0; // none of these hints should be visible initially hintContainer.validHintCount = 0; // none of these hints should be visible initially
var hints = hintContainer.childNodes; var hints = hintContainer.childNodes;
var maxhints = vimperator.options["maxhints"]; var maxhints = vimperator.options["maxhints"];
@@ -197,7 +176,7 @@ vimperator.Hints = function () //{{{
hintElem.style.left = elem.absoLeft + "px"; hintElem.style.left = elem.absoLeft + "px";
hintElem.refElem = elem; hintElem.refElem = elem;
hintContainer.valid_hint_count++; // one more visible hint in this frame hintContainer.validHintCount++; // one more visible hint in this frame
linkCount++; // and one more total hint linkCount++; // and one more total hint
} }
@@ -235,7 +214,7 @@ vimperator.Hints = function () //{{{
var hints = hintContainer.childNodes; var hints = hintContainer.childNodes;
var i, j; var i, j;
for (i = 0; i < hintContainer.valid_hint_count; i++) for (i = 0; i < hintContainer.validHintCount; i++)
{ {
hintText = formatHint(offset+i); hintText = formatHint(offset+i);
hintElem = hints[i]; hintElem = hints[i];
@@ -244,7 +223,7 @@ vimperator.Hints = function () //{{{
hintElem.innerHTML = hintText; hintElem.innerHTML = hintText;
hintElem.id = HINT_PREFIX + hintText; hintElem.id = HINT_PREFIX + hintText;
} }
offset += hintContainer.valid_hint_count; offset += hintContainer.validHintCount;
// recursively show hints // recursively show hints
for (j = 0; j < win.frames.length; j++) for (j = 0; j < win.frames.length; j++)
@@ -260,7 +239,7 @@ vimperator.Hints = function () //{{{
win = window.content; win = window.content;
var doc = win.document; var doc = win.document;
var res = vimperator.buffer.evaluateXPath("//HINTS/SPAN", doc) var res = vimperator.buffer.evaluateXPath("//HINTS/SPAN", doc);
var elem, i; var elem, i;
for (i = 0; i < res.snapshotLength; i++) for (i = 0; i < res.snapshotLength; i++)
@@ -387,283 +366,6 @@ vimperator.Hints = function () //{{{
} }
} }
////////////////////////////////////////////////////////////////////////////////
// basic functionality
////////////////////////////////////////////////////////////////////////////////
/**
* Enables the HaH-mode by showing the hints and prepare to input the
* hint numbers
*
* @author Pekka Sillanpaa
* @param event that caused the mode to change
* @return -1 if already enabled
*/
//function enableHahMode(event, mode)
this.enableHahMode = function (mode)
{
vimperator.setMode(vimperator.modes.HINTS, mode);
state = 0;
linkCount = 0;
linkNumString = "";
isHahModeEnabled = true;
createHints();
showHints(null, 0);
return true;
}
/**
* Disables the HaH-mode by hiding the hints and disabling the input mode
*
* @author Pekka Sillanpaa
* @param event that caused the mode to change
* @param action = true if something is to be clicked
* false if cancel
* @return -1 if already disabled
*/
//function disableHahMode(event)
this.disableHahMode = function (win)
{
if (!isHahModeEnabled)
return;
vimperator.setMode(vimperator.modes.NORMAL);
isHahModeEnabled = false;
linkNumString = "";
hintedElems = [];
removeHints(win);
return 0;
};
this.resetHintedElements = function ()
{
linkNumString = "";
state = 0;
while (hintedElems.length > 0)
{
var elem = hintedElems.pop();
if (!elem)
return 0;
// reset style attribute
setHintStyle(elem, vimperator.options["hintstyle"]);
}
};
this.reshowHints = function ()
{
onResize(null);
if (isHahModeEnabled)
{
removeHints();
createHints();
showHints(null, 0);
}
};
// TODO: move these functions somewhere more general
// this function 'click' an element, which also works
// for javascript links
this.openHints = function (new_tab, new_window)
{
var x = 0, y = 0;
while (hintedElems.length > 0)
{
var elem = hintedElems.pop();
if (!elem)
return 0;
setHintStyle(elem, vimperator.options["hintstyle"]);
elem = elem.refElem;
var elemTagName = elem.localName.toLowerCase();
elem.focus();
if (elemTagName == "frame" || elemTagName == "iframe")
return 0;
// for imagemap
if (elemTagName == "area")
{
var coords = elem.getAttribute("coords").split(",");
x = Number(coords[0]);
y = Number(coords[1]);
}
var doc = window.content.document;
var view = window.document.defaultView;
var evt = doc.createEvent("MouseEvents");
evt.initMouseEvent("mousedown", true, true, view, 1, x + 1, y + 1, 0, 0, /*ctrl*/ new_tab, /*event.altKey*/0, /*event.shiftKey*/ new_window, /*event.metaKey*/ new_tab, 0, null);
elem.dispatchEvent(evt);
var evt = doc.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, view, 1, x + 1, y + 1, 0, 0, /*ctrl*/ new_tab, /*event.altKey*/0, /*event.shiftKey*/ new_window, /*event.metaKey*/ new_tab, 0, null);
elem.dispatchEvent(evt);
// for 'pure' open calls without a new tab or window it doesn't
// make sense to open more hints in the current tab, open new tabs
// for it
if (!new_tab && !new_window)
new_tab = true;
}
return 0;
};
this.yankUrlHints = function ()
{
var loc = "";
var elems = this.hintedElements();
var tmp = "";
for (var i = 0; i < elems.length; i++)
{
tmp = elems[i].refElem.href;
if (typeof(tmp) != "undefined" && tmp.length > 0)
{
if (i > 0)
loc += "\n";
loc += tmp;
}
}
// disable the hints before we can echo() an information
this.disableHahMode(null, true);
vimperator.copyToClipboard(loc);
vimperator.echo("Yanked " + loc);
};
this.yankTextHints = function ()
{
var loc = "";
var elems = this.hintedElements();
var tmp = "";
for (var i = 0; i < elems.length; i++)
{
tmp = elems[i].refElem.textContent;
if (typeof(tmp) != "undefined" && tmp.length > 0)
{
if (i > 0)
loc += "\n";
loc += tmp;
}
}
// disable the hints before we can echo() an information
this.disableHahMode(null, true);
vimperator.copyToClipboard(loc);
vimperator.echo("Yanked " + loc);
};
this.saveHints = function (skip_prompt)
{
var elems = this.hintedElements();
for (var i = 0; i < elems.length; i++)
{
var doc = elems[i].ownerDocument;
var url = makeURLAbsolute(elems[i].refElem.baseURI, elems[i].refElem.href);
var text = elems[i].refElem.textContent;
try
{
urlSecurityCheck(url, doc.location.href);
saveURL(url, text, null, true, skip_prompt, makeURI(url, doc.characterSet));
}
catch (e)
{
vimperator.echoerr(e);
}
}
}
function setMouseOverElement(elem)
{
var doc = window.document;
var elemTagName = elem.localName.toLowerCase();
if (elemTagName == "frame" || elemTagName == "iframe")
{
elem.contentWindow.focus();
return;
}
//else
//{
// elem.focus();
//}
var evt = doc.createEvent("MouseEvents");
var x = 0;
var y = 0;
// for imagemap
if (elemTagName == "area")
{
var coords = elem.getAttribute("coords").split(",");
x = Number(coords[0]);
y = Number(coords[1]);
}
evt.initMouseEvent("mouseover", true, true, doc.defaultView, 1, x, y, 0, 0, 0, 0, 0, 0, 0, null);
elem.dispatchEvent(evt);
}
////////////////////////////////////////////////////////////////////////////////
// event handlers
////////////////////////////////////////////////////////////////////////////////
// returns nr. of fully parsed links when a new hint has been found,
// otherwise 0 if current state is part of a hint, or -1 if an error occured
// (like we have typed keys which never can become a hint
this.processEvent = function (event)
{
if (!isHahModeEnabled)
return -1;
// reset state to show that we are in processing mode
state = 0;
var num = String.fromCharCode(event.charCode).toUpperCase();
var hintCharacters = vimperator.options["hintchars"];
if (num != null && hintCharacters.toUpperCase().indexOf(num) > -1)
{
var oldLinkNumString = linkNumString;
linkNumString += "" + num;
// update reference to currently selected node;
var elem = getHintById(linkNumString);
changeHintFocus(linkNumString, oldLinkNumString);
// if we found the hint, fine just return it
if (elem)
{
hintedElems.push(elem);
linkNumString = "";
state = 1;
return hintedElems.length;
}
//calculate how many characters a hint must have
var hintLength = 1;
var tmp = linkCount;
while ((tmp /= hintCharacters.length) > 1.0)
hintLength++;
if (linkNumString.length >= hintLength)
return -1;
else
return 0;
}
// an unparseable or wrong key
return -1;
}
function genHintContainer(doc) function genHintContainer(doc)
{ {
if (doc.getElementsByTagName("HINTS").length > 0) if (doc.getElementsByTagName("HINTS").length > 0)
@@ -671,7 +373,7 @@ vimperator.Hints = function () //{{{
hints = doc.createElement("HINTS"); hints = doc.createElement("HINTS");
hints.id = "hah_hints"; hints.id = "hah_hints";
hints.valid_hint_count = 0; // initially 0 elements are usable as hints hints.validHintCount = 0; // initially 0 elements are usable as hints
if (doc.body) if (doc.body)
doc.body.appendChild(hints); doc.body.appendChild(hints);
@@ -706,16 +408,329 @@ vimperator.Hints = function () //{{{
linkNumString = ""; linkNumString = "";
isHahModeEnabled = true; isHahModeEnabled = true;
setTimeout( function () { setTimeout(function () {
createHints(); createHints();
showHints(null, 0); showHints(null, 0);
}, 100); }, 100);
} }
} }
function setMouseOverElement(elem)
{
var doc = window.document;
var elemTagName = elem.localName.toLowerCase();
if (elemTagName == "frame" || elemTagName == "iframe")
{
elem.contentWindow.focus();
return;
}
//else
//{
// elem.focus();
//}
var evt = doc.createEvent("MouseEvents");
var x = 0;
var y = 0;
// for imagemap
if (elemTagName == "area")
{
var coords = elem.getAttribute("coords").split(",");
x = Number(coords[0]);
y = Number(coords[1]);
}
evt.initMouseEvent("mouseover", true, true, doc.defaultView, 1, x, y, 0, 0, 0, 0, 0, 0, 0, null);
elem.dispatchEvent(evt);
}
/////////////////////////////////////////////////////////////////////////////}}}
////////////////////// PUBLIC SECTION //////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
var hintManager = {
get hintedElements() { return hintedElems; },
get currentState() { return state; },
get setCurrentState(s) { state = s; },
loadCoord: function (winId, i)
{
win = wins[winId];
// win.res is not ready when loading has not finished yet
if (!win.res)
return;
var elem = win.res.snapshotItem(i);
if (elem)
genElemCoords(elem);
i++;
if (i < win.res.snapshotLength && !isHahModeEnabled)
window.setTimeout("vimperator.hints.loadCoord(" + winId + ", "+ i +");", 1);
else
win.coordLoaderId = null;
},
////////////////////////////////////////////////////////////////////////////////
// basic functionality
////////////////////////////////////////////////////////////////////////////////
/**
* Enables the HaH-mode by showing the hints and prepare to input the
* hint numbers
*
* @author Pekka Sillanpaa
* @param event that caused the mode to change
* @return -1 if already enabled
*/
//function enableHahMode(event, mode)
enableHahMode: function (mode)
{
vimperator.setMode(vimperator.modes.HINTS, mode);
state = 0;
linkCount = 0;
linkNumString = "";
isHahModeEnabled = true;
createHints();
showHints(null, 0);
return true;
},
/**
* Disables the HaH-mode by hiding the hints and disabling the input mode
*
* @author Pekka Sillanpaa
* @param event that caused the mode to change
* @param action = true if something is to be clicked
* false if cancel
* @return -1 if already disabled
*/
//function disableHahMode(event)
disableHahMode: function (win)
{
if (!isHahModeEnabled)
return;
vimperator.setMode(vimperator.modes.NORMAL);
isHahModeEnabled = false;
linkNumString = "";
hintedElems = [];
removeHints(win);
return 0;
},
resetHintedElements: function ()
{
linkNumString = "";
state = 0;
while (hintedElems.length > 0)
{
var elem = hintedElems.pop();
if (!elem)
return 0;
// reset style attribute
setHintStyle(elem, vimperator.options["hintstyle"]);
}
},
reshowHints: function ()
{
onResize(null);
if (isHahModeEnabled)
{
removeHints();
createHints();
showHints(null, 0);
}
},
// TODO: move these functions somewhere more general
// this function 'click' an element, which also works
// for javascript links
openHints: function (newTab, newWindow)
{
var x = 0, y = 0;
while (hintedElems.length > 0)
{
var elem = hintedElems.pop();
if (!elem)
return 0;
setHintStyle(elem, vimperator.options["hintstyle"]);
elem = elem.refElem;
var elemTagName = elem.localName.toLowerCase();
elem.focus();
if (elemTagName == "frame" || elemTagName == "iframe")
return 0;
// for imagemap
if (elemTagName == "area")
{
var coords = elem.getAttribute("coords").split(",");
x = Number(coords[0]);
y = Number(coords[1]);
}
var doc = window.content.document;
var view = window.document.defaultView;
var evt = doc.createEvent("MouseEvents");
evt.initMouseEvent("mousedown", true, true, view, 1, x + 1, y + 1, 0, 0, /*ctrl*/ newTab, /*event.altKey*/0, /*event.shiftKey*/ newWindow, /*event.metaKey*/ newTab, 0, null);
elem.dispatchEvent(evt);
var evt = doc.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, view, 1, x + 1, y + 1, 0, 0, /*ctrl*/ newTab, /*event.altKey*/0, /*event.shiftKey*/ newWindow, /*event.metaKey*/ newTab, 0, null);
elem.dispatchEvent(evt);
// for 'pure' open calls without a new tab or window it doesn't
// make sense to open more hints in the current tab, open new tabs
// for it
if (!newTab && !newWindow)
newTab = true;
}
return 0;
},
yankUrlHints: function ()
{
var loc = "";
var elems = this.hintedElements();
var tmp = "";
for (var i = 0; i < elems.length; i++)
{
tmp = elems[i].refElem.href;
if (typeof tmp != "undefined" && tmp.length > 0)
{
if (i > 0)
loc += "\n";
loc += tmp;
}
}
// disable the hints before we can echo() an information
this.disableHahMode(null, true);
vimperator.copyToClipboard(loc);
vimperator.echo("Yanked " + loc);
},
yankTextHints: function ()
{
var loc = "";
var elems = this.hintedElements();
var tmp = "";
for (var i = 0; i < elems.length; i++)
{
tmp = elems[i].refElem.textContent;
if (typeof tmp != "undefined" && tmp.length > 0)
{
if (i > 0)
loc += "\n";
loc += tmp;
}
}
// disable the hints before we can echo() an information
this.disableHahMode(null, true);
vimperator.copyToClipboard(loc);
vimperator.echo("Yanked " + loc);
},
saveHints: function (skipPrompt)
{
var elems = this.hintedElements();
for (var i = 0; i < elems.length; i++)
{
var doc = elems[i].ownerDocument;
var url = makeURLAbsolute(elems[i].refElem.baseURI, elems[i].refElem.href);
var text = elems[i].refElem.textContent;
try
{
urlSecurityCheck(url, doc.location.href);
saveURL(url, text, null, true, skipPrompt, makeURI(url, doc.characterSet));
}
catch (e)
{
vimperator.echoerr(e);
}
}
},
////////////////////////////////////////////////////////////////////////////////
// event handlers
////////////////////////////////////////////////////////////////////////////////
// returns nr. of fully parsed links when a new hint has been found,
// otherwise 0 if current state is part of a hint, or -1 if an error occured
// (like we have typed keys which never can become a hint
processEvent: function (event)
{
if (!isHahModeEnabled)
return -1;
// reset state to show that we are in processing mode
state = 0;
var num = String.fromCharCode(event.charCode).toUpperCase();
var hintCharacters = vimperator.options["hintchars"];
if (num != null && hintCharacters.toUpperCase().indexOf(num) > -1)
{
var oldLinkNumString = linkNumString;
linkNumString += "" + num;
// update reference to currently selected node;
var elem = getHintById(linkNumString);
changeHintFocus(linkNumString, oldLinkNumString);
// if we found the hint, fine just return it
if (elem)
{
hintedElems.push(elem);
linkNumString = "";
state = 1;
return hintedElems.length;
}
//calculate how many characters a hint must have
var hintLength = 1;
var tmp = linkCount;
while ((tmp /= hintCharacters.length) > 1.0)
hintLength++;
if (linkNumString.length >= hintLength)
return -1;
else
return 0;
}
// an unparseable or wrong key
return -1;
}
};
window.document.addEventListener("DOMContentLoaded", initDoc, null); window.document.addEventListener("DOMContentLoaded", initDoc, null);
// FIXME: add resize support // FIXME: add resize support
//window.addEventListener("resize", onResize, null); //window.addEventListener("resize", onResize, null);
} //}}}
return hintManager;
//}}}
}; //}}}
// vim: set fdm=marker sw=4 ts=4 et: // vim: set fdm=marker sw=4 ts=4 et:

View File

@@ -27,9 +27,9 @@ the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL. the terms of any one of the MPL, the GPL or the LGPL.
}}} ***** END LICENSE BLOCK *****/ }}} ***** END LICENSE BLOCK *****/
vimperator.IO = function () vimperator.IO = function () //{{{
{ {
var environment_service = Components.classes["@mozilla.org/process/environment;1"] var environmentService = Components.classes["@mozilla.org/process/environment;1"]
.getService(Components.interfaces.nsIEnvironment); .getService(Components.interfaces.nsIEnvironment);
return { return {
@@ -54,30 +54,30 @@ vimperator.IO = function ()
// expand "~" to VIMPERATOR_HOME or HOME (USERPROFILE or HOMEDRIVE\HOMEPATH on Windows if HOME is not set) // expand "~" to VIMPERATOR_HOME or HOME (USERPROFILE or HOMEDRIVE\HOMEPATH on Windows if HOME is not set)
if (/^~/.test(path)) if (/^~/.test(path))
{ {
var home = environment_service.get("VIMPERATOR_HOME"); var home = environmentService.get("VIMPERATOR_HOME");
if (!home) if (!home)
home = environment_service.get("HOME"); home = environmentService.get("HOME");
if (WINDOWS && !home) if (WINDOWS && !home)
home = environment_service.get("USERPROFILE") || home = environmentService.get("USERPROFILE") ||
environment_service.get("HOMEDRIVE") + environment_service.get("HOMEPATH"); environmentService.get("HOMEDRIVE") + environmentService.get("HOMEPATH");
path = path.replace("~", home); path = path.replace("~", home);
} }
// expand any $ENV vars // expand any $ENV vars
var env_vars = path.match(/\$\w+\b/g); // this is naive but so is Vim and we like to be compatible var envVars = path.match(/\$\w+\b/g); // this is naive but so is Vim and we like to be compatible
if (env_vars) if (envVars)
{ {
var expansion; var expansion;
for (var i = 0; i < env_vars.length; i++) for (var i = 0; i < envVars.length; i++)
{ {
expansion = environment_service.get(env_vars[i].replace("$", "")); expansion = environmentService.get(envVars[i].replace("$", ""));
if (expansion) if (expansion)
path = path.replace(env_vars[i], expansion); path = path.replace(envVars[i], expansion);
} }
} }
@@ -86,30 +86,30 @@ vimperator.IO = function ()
getPluginDir: function () getPluginDir: function ()
{ {
var plugin_dir; var pluginDir;
if (navigator.platform == "Win32") if (navigator.platform == "Win32")
plugin_dir = "~/vimperator/plugin"; pluginDir = "~/vimperator/plugin";
else else
plugin_dir = "~/.vimperator/plugin"; pluginDir = "~/.vimperator/plugin";
plugin_dir = this.getFile(this.expandPath(plugin_dir)); pluginDir = this.getFile(this.expandPath(pluginDir));
return plugin_dir.exists() && plugin_dir.isDirectory() ? plugin_dir : null; return pluginDir.exists() && pluginDir.isDirectory() ? pluginDir : null;
}, },
getRCFile: function () getRCFile: function ()
{ {
var rc_file1 = this.getFile(this.expandPath("~/.vimperatorrc")); var rcFile1 = this.getFile(this.expandPath("~/.vimperatorrc"));
var rc_file2 = this.getFile(this.expandPath("~/_vimperatorrc")); var rcFile2 = this.getFile(this.expandPath("~/_vimperatorrc"));
if (navigator.platform == "Win32") if (navigator.platform == "Win32")
[rc_file1, rc_file2] = [rc_file2, rc_file1] [rcFile1, rcFile2] = [rcFile2, rcFile1]
if (rc_file1.exists() && rc_file1.isFile()) if (rcFile1.exists() && rcFile1.isFile())
return rc_file1; return rcFile1;
else if (rc_file2.exists() && rc_file2.isFile()) else if (rcFile2.exists() && rcFile2.isFile())
return rc_file2; return rcFile2;
else else
return null; return null;
}, },
@@ -133,12 +133,12 @@ vimperator.IO = function ()
createInstance(Components.interfaces.nsILocalFile); createInstance(Components.interfaces.nsILocalFile);
if (navigator.platform == "Win32") if (navigator.platform == "Win32")
{ {
var dir = environment_service.get("TMP") || environment_service.get("TEMP") || "C:\\"; var dir = environmentService.get("TMP") || environmentService.get("TEMP") || "C:\\";
file.initWithPath(dir + "\\vimperator.tmp"); file.initWithPath(dir + "\\vimperator.tmp");
} }
else else
{ {
var dir = environment_service.get("TMP") || environment_service.get("TEMP") || "/tmp/"; var dir = environmentService.get("TMP") || environmentService.get("TEMP") || "/tmp/";
file.initWithPath(dir + "/vimperator.tmp"); file.initWithPath(dir + "/vimperator.tmp");
} }
@@ -234,7 +234,7 @@ vimperator.IO = function ()
ocstream.close(); ocstream.close();
ofstream.close(); ofstream.close();
} }
} };
} }; //}}}
// vim: set fdm=marker sw=4 ts=4 et: // vim: set fdm=marker sw=4 ts=4 et:

File diff suppressed because it is too large Load Diff

View File

@@ -26,7 +26,7 @@ the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL. the terms of any one of the MPL, the GPL or the LGPL.
}}} ***** END LICENSE BLOCK *****/ }}} ***** END LICENSE BLOCK *****/
vimperator.Option = function (names, type, extra_info) //{{{ vimperator.Option = function (names, type, extraInfo) //{{{
{ {
if (!names || !type) if (!names || !type)
return null; return null;
@@ -38,29 +38,29 @@ vimperator.Option = function (names, type, extra_info) //{{{
this.usage = this.names; this.usage = this.names;
this.type = type; this.type = type;
if (extra_info) if (extraInfo)
{ {
if (extra_info.usage) if (extraInfo.usage)
this.usage = extra_info.usage; this.usage = extraInfo.usage;
this.help = extra_info.help || null; this.help = extraInfo.help || null;
this.short_help = extra_info.short_help || null; this.shortHelp = extraInfo.shortHelp || null;
// "", 0 are valid default values // "", 0 are valid default values
if (extra_info.default_value !== undefined) if (extraInfo.defaultValue !== undefined)
this.default_value = extra_info.default_value; this.defaultValue = extraInfo.defaultValue;
else else
this.default_value = null; this.defaultValue = null;
value = this.default_value; value = this.defaultValue;
if (extra_info.setter) if (extraInfo.setter)
this.setter = extra_info.setter; this.setter = extraInfo.setter;
if (extra_info.getter) if (extraInfo.getter)
this.getter = extra_info.getter; this.getter = extraInfo.getter;
this.completer = extra_info.completer || null; this.completer = extraInfo.completer || null;
this.validator = extra_info.validator || null; this.validator = extraInfo.validator || null;
} }
// add noOPTION variant of boolean OPTION to this.names // add noOPTION variant of boolean OPTION to this.names
@@ -85,9 +85,9 @@ vimperator.Option = function (names, type, extra_info) //{{{
} }
); );
this.__defineSetter__("value", this.__defineSetter__("value",
function (new_value) function (newValue)
{ {
value = new_value; value = newValue;
if (this.setter) if (this.setter)
this.setter.call(this, value); this.setter.call(this, value);
} }
@@ -104,7 +104,7 @@ vimperator.Option = function (names, type, extra_info) //{{{
return true; return true;
} }
return false; return false;
} };
this.isValidValue = function (value) this.isValidValue = function (value)
{ {
@@ -112,26 +112,27 @@ vimperator.Option = function (names, type, extra_info) //{{{
return this.validator(value); return this.validator(value);
else else
return true; return true;
} };
this.reset = function () this.reset = function ()
{ {
this.value = this.default_value; this.value = this.defaultValue;
} };
} //}}} }; //}}}
vimperator.Options = function () //{{{ vimperator.Options = function () //{{{
{ {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
////////////////////// PRIVATE SECTION ///////////////////////////////////////// ////////////////////// PRIVATE SECTION /////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
var firefox_prefs = Components.classes["@mozilla.org/preferences-service;1"]
var firefoxPrefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch); .getService(Components.interfaces.nsIPrefBranch);
var vimperator_prefs = firefox_prefs.getBranch("extensions.vimperator."); var vimperatorPrefs = firefoxPrefs.getBranch("extensions.vimperator.");
var options = []; var options = [];
// save if we already changed a GUI related option, used for setInitialGUI // save if we already changed a GUI related option, used for setInitialGUI
var guioptions_done = false, showtabline_done = false, laststatus_done = false; var guioptionsDone = false, showtablineDone = false, laststatusDone = false;
function optionsIterator() function optionsIterator()
{ {
@@ -141,14 +142,14 @@ vimperator.Options = function () //{{{
throw StopIteration; throw StopIteration;
} }
function storePreference(name, value, vimperator_branch) function storePreference(name, value, vimperatorBranch)
{ {
var branch; var branch;
if (vimperator_branch) if (vimperatorBranch)
branch = vimperator_prefs; branch = vimperatorPrefs;
else else
branch = firefox_prefs; branch = firefoxPrefs;
switch (typeof value) switch (typeof value)
{ {
@@ -166,23 +167,23 @@ vimperator.Options = function () //{{{
} }
} }
function loadPreference(name, forced_default, vimperator_branch) function loadPreference(name, forcedDefault, vimperatorBranch)
{ {
var default_value = null; var defaultValue = null;
if (forced_default != null) // this argument sets defaults for non-user settable options (like comp_history) if (forcedDefault != null) // this argument sets defaults for non-user settable options (like comp_history)
default_value = forced_default; defaultValue = forcedDefault;
if (vimperator_branch) if (vimperatorBranch)
{ {
branch = vimperator_prefs; branch = vimperatorPrefs;
if (!forced_default) // this argument sets defaults for non-user settable options (like comp_history) if (!forcedDefault) // this argument sets defaults for non-user settable options (like comp_history)
{ {
for (var i = 0; i < options.length; i++) for (var i = 0; i < options.length; i++)
{ {
if (options[i].name == name) // only first name is searched if (options[i].name == name) // only first name is searched
{ {
default_value = options[i].default_value; defaultValue = options[i].defaultValue;
break; break;
} }
} }
@@ -190,12 +191,12 @@ vimperator.Options = function () //{{{
} }
else else
{ {
branch = firefox_prefs; branch = firefoxPrefs;
} }
try try
{ {
switch (typeof default_value) switch (typeof defaultValue)
{ {
case "string": case "string":
return branch.getCharPref(name); return branch.getCharPref(name);
@@ -204,12 +205,12 @@ vimperator.Options = function () //{{{
case "boolean": case "boolean":
return branch.getBoolPref(name); return branch.getBoolPref(name);
default: default:
return default_value; return defaultValue;
} }
} }
catch (e) catch (e)
{ {
return default_value; return defaultValue;
} }
} }
@@ -225,7 +226,7 @@ vimperator.Options = function () //{{{
document.getElementById("PersonalToolbar").collapsed = value.indexOf("b") > -1 ? false : true; document.getElementById("PersonalToolbar").collapsed = value.indexOf("b") > -1 ? false : true;
document.getElementById("PersonalToolbar").hidden = value.indexOf("b") > -1 ? false : true; document.getElementById("PersonalToolbar").hidden = value.indexOf("b") > -1 ? false : true;
guioptions_done = true; guioptionsDone = true;
} }
function setLastStatus(value) function setLastStatus(value)
@@ -245,7 +246,7 @@ vimperator.Options = function () //{{{
document.getElementById("status-bar").hidden = false; document.getElementById("status-bar").hidden = false;
} }
laststatus_done = true; laststatusDone = true;
} }
function setShowTabline(value) function setShowTabline(value)
@@ -269,7 +270,7 @@ vimperator.Options = function () //{{{
tabs.collapsed = false; tabs.collapsed = false;
} }
showtabline_done = true; showtablineDone = true;
} }
function setTitleString(value) function setTitleString(value)
@@ -296,9 +297,9 @@ vimperator.Options = function () //{{{
// //
// work around firefox popup blocker // work around firefox popup blocker
var popup_allowed_events = loadPreference("dom.popup_allowed_events", "change click dblclick mouseup reset submit"); var popupAllowedEvents = loadPreference("dom.popup_allowed_events", "change click dblclick mouseup reset submit");
if (!popup_allowed_events.match("keypress")) if (!popupAllowedEvents.match("keypress"))
storePreference("dom.popup_allowed_events", popup_allowed_events + " keypress"); storePreference("dom.popup_allowed_events", popupAllowedEvents + " keypress");
// TODO: shouldn't we be resetting these in destroy() as well? // TODO: shouldn't we be resetting these in destroy() as well?
// we have our own typeahead find implementation // we have our own typeahead find implementation
@@ -312,110 +313,114 @@ vimperator.Options = function () //{{{
////////////////////// PUBLIC SECTION ////////////////////////////////////////// ////////////////////// PUBLIC SECTION //////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
this.__iterator__ = function () var optionManager = {
{
return optionsIterator();
}
this.get = function (name) __iterator__: function ()
{
for (var i = 0; i < options.length; i++)
{ {
if (options[i].hasName(name)) return optionsIterator();
return options[i]; },
}
return null;
}
this.add = function (option) get: function (name)
{
this.__defineGetter__(option.name, function () { return option.value; });
this.__defineSetter__(option.name, function (value) { option.value = value; });
options.push(option);
}
this.destroy = function ()
{
// reset some modified firefox prefs
if (loadPreference("dom.popup_allowed_events", "change click dblclick mouseup reset submit")
== popup_allowed_events + " keypress")
storePreference("dom.popup_allowed_events", popup_allowed_events);
}
this.list = function (only_non_default)
{
// TODO: columns like Vim?
var list = ":" + vimperator.util.escapeHTML(vimperator.commandline.getCommand()) + "<br/>" +
"<table><tr align=\"left\" class=\"hl-Title\"><th>--- Options ---</th></tr>";
var name, value, def;
for (var i = 0; i < options.length; i++)
{ {
name = options[i].name; for (var i = 0; i < options.length; i++)
value = options[i].value;
def = options[i].default_value;
if (only_non_default && value == def)
continue;
if (options[i].type == "boolean")
{ {
name = value ? " " + name : "no" + name; if (options[i].hasName(name))
if (value != def) return options[i];
name = "<span style=\"font-weight: bold\">" + name + "</span><span style=\"color: gray\"> (default: " + (def ? "" : "no") + options[i].name + ")</span>";
list += "<tr><td>" + name + "</td></tr>";
} }
else return null;
},
add: function (option)
{
this.__defineGetter__(option.name, function () { return option.value; });
this.__defineSetter__(option.name, function (value) { option.value = value; });
options.push(option);
},
destroy: function ()
{
// reset some modified firefox prefs
if (loadPreference("dom.popup_allowed_events", "change click dblclick mouseup reset submit")
== popupAllowedEvents + " keypress")
storePreference("dom.popup_allowed_events", popupAllowedEvents);
},
list: function (onlyNondefault)
{
// TODO: columns like Vim?
var list = ":" + vimperator.util.escapeHTML(vimperator.commandline.getCommand()) + "<br/>" +
"<table><tr align=\"left\" class=\"hl-Title\"><th>--- Options ---</th></tr>";
var name, value, def;
for (var i = 0; i < options.length; i++)
{ {
if (value != def) name = options[i].name;
value = options[i].value;
def = options[i].defaultValue;
if (onlyNondefault && value == def)
continue;
if (options[i].type == "boolean")
{ {
name = "<span style=\"font-weight: bold\">" + name + "</span>"; name = value ? " " + name : "no" + name;
value = vimperator.util.colorize(value, false) + "<span style=\"color: gray\"> (default: " + def + ")</span>"; if (value != def)
name = "<span style=\"font-weight: bold\">" + name + "</span><span style=\"color: gray\"> (default: " + (def ? "" : "no") + options[i].name + ")</span>";
list += "<tr><td>" + name + "</td></tr>";
} }
else else
value = vimperator.util.colorize(value, false); {
if (value != def)
{
name = "<span style=\"font-weight: bold\">" + name + "</span>";
value = vimperator.util.colorize(value, false) + "<span style=\"color: gray\"> (default: " + def + ")</span>";
}
else
value = vimperator.util.colorize(value, false);
list += "<tr><td>" + " " + name + "=" + value + "</td></tr>"; list += "<tr><td>" + " " + name + "=" + value + "</td></tr>";
}
} }
list += "</table>";
vimperator.commandline.echo(list, vimperator.commandline.HL_NORMAL, vimperator.commandline.FORCE_MULTILINE);
},
// this hack is only needed, because we need to do asynchronous loading of the .vimperatorrc
setInitialGUI: function ()
{
if (!guioptionsDone)
this.get("guioptions").reset();
if (!laststatusDone)
this.get("laststatus").reset();
if (!showtablineDone)
this.get("showtabline").reset();
},
// TODO: separate Preferences from Options? Would these utility functions
// be better placed in the 'core' vimperator namespace somewhere?
setPref: function (name, value)
{
return storePreference(name, value, true);
},
getPref: function (name, forcedDefault)
{
return loadPreference(name, forcedDefault, true);
},
setFirefoxPref: function (name, value)
{
return storePreference(name, value);
},
getFirefoxPref: function (name, forcedDefault)
{
return loadPreference(name, forcedDefault);
} }
list += "</table>"; };
vimperator.commandline.echo(list, vimperator.commandline.HL_NORMAL, vimperator.commandline.FORCE_MULTILINE);
}
// this hack is only needed, because we need to do asynchronous loading of the .vimperatorrc
this.setInitialGUI = function ()
{
if (!guioptions_done)
this.get("guioptions").reset();
if (!laststatus_done)
this.get("laststatus").reset();
if (!showtabline_done)
this.get("showtabline").reset();
}
// TODO: separate Preferences from Options? Would these utility functions
// be better placed in the 'core' vimperator namespace somewhere?
this.setPref = function (name, value)
{
return storePreference(name, value, true);
}
this.getPref = function (name, forced_default)
{
return loadPreference(name, forced_default, true);
}
this.setFirefoxPref = function (name, value)
{
return storePreference(name, value);
}
this.getFirefoxPref = function (name, forced_default)
{
return loadPreference(name, forced_default);
}
/////////////////////////////////////////////////////////////////////////////}}} /////////////////////////////////////////////////////////////////////////////}}}
////////////////////// DEFAULT OPTIONS ///////////////////////////////////////// ////////////////////// DEFAULT OPTIONS /////////////////////////////////////////
@@ -424,11 +429,11 @@ vimperator.Options = function () //{{{
const DEFAULT_HINTTAGS = "//*[@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @class='lk' or @class='s'] | " + const DEFAULT_HINTTAGS = "//*[@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @class='lk' or @class='s'] | " +
"//input[not(@type='hidden')] | //a | //area | //iframe | //textarea | //button | //select | " + "//input[not(@type='hidden')] | //a | //area | //iframe | //textarea | //button | //select | " +
"//xhtml:*[@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @class='lk' or @class='s'] | " + "//xhtml:*[@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @class='lk' or @class='s'] | " +
"//xhtml:input[not(@type='hidden')] | //xhtml:a | //xhtml:area | //xhtml:iframe | //xhtml:textarea | //xhtml:button | //xhtml:select" "//xhtml:input[not(@type='hidden')] | //xhtml:a | //xhtml:area | //xhtml:iframe | //xhtml:textarea | //xhtml:button | //xhtml:select";
this.add(new vimperator.Option(["activate", "act"], "stringlist", optionManager.add(new vimperator.Option(["activate", "act"], "stringlist",
{ {
short_help: "Define when tabs are automatically activated", shortHelp: "Define when tabs are automatically activated",
help: "Available items:<br/>" + help: "Available items:<br/>" +
"<ul>" + "<ul>" +
"<li><b>homepage</b>: <code class=\"mapping\">gH</code> mapping</li>" + "<li><b>homepage</b>: <code class=\"mapping\">gH</code> mapping</li>" +
@@ -436,16 +441,16 @@ vimperator.Options = function () //{{{
"<li><b>tabopen</b>: <code class=\"command\">:tabopen[!]</code> command</li>" + "<li><b>tabopen</b>: <code class=\"command\">:tabopen[!]</code> command</li>" +
"<li><b>paste</b>: <code class=\"mapping\">P</code> and <code class=\"mapping\">gP</code> mappings</li>" + "<li><b>paste</b>: <code class=\"mapping\">P</code> and <code class=\"mapping\">gP</code> mappings</li>" +
"</ul>", "</ul>",
default_value: "homepage,quickmark,tabopen,paste", defaultValue: "homepage,quickmark,tabopen,paste",
validator: function (value) validator: function (value)
{ {
return value.split(",").every(function (item) { return /^(homepage|quickmark|tabopen|paste|)$/.test(item); }); return value.split(",").every(function (item) { return /^(homepage|quickmark|tabopen|paste|)$/.test(item); });
} }
} }
)); ));
this.add(new vimperator.Option(["complete", "cpt"], "charlist", optionManager.add(new vimperator.Option(["complete", "cpt"], "charlist",
{ {
short_help: "Items which are completed at the :[tab]open prompt", shortHelp: "Items which are completed at the :[tab]open prompt",
help: "Available items:<br/>" + help: "Available items:<br/>" +
"<ul>" + "<ul>" +
"<li><b>s</b>: Search engines and keyword URLs</li>" + "<li><b>s</b>: Search engines and keyword URLs</li>" +
@@ -455,43 +460,42 @@ vimperator.Options = function () //{{{
"</ul>" + "</ul>" +
"The order is important, so <code class=\"command\">:set complete=bs</code> would list bookmarks first, and then any available quick searches.<br/>" + "The order is important, so <code class=\"command\">:set complete=bs</code> would list bookmarks first, and then any available quick searches.<br/>" +
"Add <code class=\"option\">'sort'</code> to the <code class=\"option\">'wildoptions'</code> option if you want all entries sorted.", "Add <code class=\"option\">'sort'</code> to the <code class=\"option\">'wildoptions'</code> option if you want all entries sorted.",
default_value: "sfbh", defaultValue: "sfbh",
validator: function (value) { return !/[^sfbh]/.test(value); } validator: function (value) { return !/[^sfbh]/.test(value); }
} }
)); ));
this.add(new vimperator.Option(["defsearch", "ds"], "string", optionManager.add(new vimperator.Option(["defsearch", "ds"], "string",
{ {
short_help: "Set the default search engine", shortHelp: "Set the default search engine",
help: "The default search engine is used in the <code class=\"command\">:[tab]open [arg]</code> command " + help: "The default search engine is used in the <code class=\"command\">:[tab]open [arg]</code> command " +
"if [arg] neither looks like a URL or like a specified search engine/keyword.", "if [arg] neither looks like a URL or like a specified search engine/keyword.",
completer: function () { return [["foo", "bar"], ["shit", "blub"]]; }, defaultValue: "google"
default_value: "google"
} }
)); ));
this.add(new vimperator.Option(["extendedhinttags", "eht"], "string", optionManager.add(new vimperator.Option(["extendedhinttags", "eht"], "string",
{ {
short_help: "XPath string of hintable elements activated by ';'", shortHelp: "XPath string of hintable elements activated by ';'",
default_value: DEFAULT_HINTTAGS defaultValue: DEFAULT_HINTTAGS
} }
)); ));
this.add(new vimperator.Option(["focusedhintstyle", "fhs"], "string", optionManager.add(new vimperator.Option(["focusedhintstyle", "fhs"], "string",
{ {
short_help: "CSS specification of focused hints", shortHelp: "CSS specification of focused hints",
default_value: "z-index:5000; font-family:monospace; font-size:12px; color:ButtonText; background-color:ButtonShadow; " + defaultValue: "z-index:5000; font-family:monospace; font-size:12px; color:ButtonText; background-color:ButtonShadow; " +
"border-color:ButtonShadow; border-width:1px; border-style:solid; padding:0px 1px 0px 1px; position:absolute;" "border-color:ButtonShadow; border-width:1px; border-style:solid; padding:0px 1px 0px 1px; position:absolute;"
} }
)); ));
this.add(new vimperator.Option(["fullscreen", "fs"], "boolean", optionManager.add(new vimperator.Option(["fullscreen", "fs"], "boolean",
{ {
short_help: "Show the current window fullscreen", shortHelp: "Show the current window fullscreen",
setter: function (value) { window.fullScreen = value; }, setter: function (value) { window.fullScreen = value; },
getter: function () { return window.fullScreen; }, getter: function () { return window.fullScreen; },
default_value: false defaultValue: false
} }
)); ));
this.add(new vimperator.Option(["guioptions", "go"], "charlist", optionManager.add(new vimperator.Option(["guioptions", "go"], "charlist",
{ {
short_help: "Show or hide the menu, toolbar and scrollbars", shortHelp: "Show or hide the menu, toolbar and scrollbars",
help: "Supported characters:<br/>" + help: "Supported characters:<br/>" +
"<ul>" + "<ul>" +
"<li><b>m</b>: menubar</li>" + "<li><b>m</b>: menubar</li>" +
@@ -499,58 +503,58 @@ vimperator.Options = function () //{{{
"<li><b>b</b>: bookmark bar</li>" + "<li><b>b</b>: bookmark bar</li>" +
"</ul>", "</ul>",
setter: function (value) { setGuiOptions(value); }, setter: function (value) { setGuiOptions(value); },
default_value: "", defaultValue: "",
validator: function (value) { return !/[^mTb]/.test(value); } validator: function (value) { return !/[^mTb]/.test(value); }
} }
)); ));
this.add(new vimperator.Option(["hintchars", "hc"], "charlist", optionManager.add(new vimperator.Option(["hintchars", "hc"], "charlist",
{ {
short_help: "String of single characters which can be used to follow hints", shortHelp: "String of single characters which can be used to follow hints",
default_value: "hjklasdfgyuiopqwertnmzxcvb" defaultValue: "hjklasdfgyuiopqwertnmzxcvb"
} }
)); ));
this.add(new vimperator.Option(["hintstyle", "hs"], "string", optionManager.add(new vimperator.Option(["hintstyle", "hs"], "string",
{ {
short_help: "CSS specification of unfocused hints", shortHelp: "CSS specification of unfocused hints",
default_value: "z-index:5000; font-family:monospace; font-size:12px; color:white; background-color:red; " + defaultValue: "z-index:5000; font-family:monospace; font-size:12px; color:white; background-color:red; " +
"border-color:ButtonShadow; border-width:0px; border-style:solid; padding:0px 1px 0px 1px; position:absolute;" "border-color:ButtonShadow; border-width:0px; border-style:solid; padding:0px 1px 0px 1px; position:absolute;"
} }
)); ));
this.add(new vimperator.Option(["hinttags", "ht"], "string", optionManager.add(new vimperator.Option(["hinttags", "ht"], "string",
{ {
short_help: "XPath string of hintable elements activated by <code class=\"mapping\">'f'</code> and <code class=\"mapping\">'F'</code>", shortHelp: "XPath string of hintable elements activated by <code class=\"mapping\">'f'</code> and <code class=\"mapping\">'F'</code>",
default_value: DEFAULT_HINTTAGS defaultValue: DEFAULT_HINTTAGS
} }
)); ));
this.add(new vimperator.Option(["hlsearch", "hls"], "boolean", optionManager.add(new vimperator.Option(["hlsearch", "hls"], "boolean",
{ {
short_help: "Highlight previous search pattern matches", shortHelp: "Highlight previous search pattern matches",
setter: function (value) { if (value) vimperator.search.highlight(); else vimperator.search.clear(); }, setter: function (value) { if (value) vimperator.search.highlight(); else vimperator.search.clear(); },
default_value: false defaultValue: false
} }
)); ));
this.add(new vimperator.Option(["hlsearchstyle", "hlss"], "string", optionManager.add(new vimperator.Option(["hlsearchstyle", "hlss"], "string",
{ {
short_help: "CSS specification of highlighted search items", shortHelp: "CSS specification of highlighted search items",
default_value: "color: black; background-color: yellow; padding: 0; display: inline;" defaultValue: "color: black; background-color: yellow; padding: 0; display: inline;"
} }
)); ));
this.add(new vimperator.Option(["ignorecase", "ic"], "boolean", optionManager.add(new vimperator.Option(["ignorecase", "ic"], "boolean",
{ {
short_help: "Ignore case in search patterns", shortHelp: "Ignore case in search patterns",
default_value: true defaultValue: true
} }
)); ));
this.add(new vimperator.Option(["incsearch", "is"], "boolean", optionManager.add(new vimperator.Option(["incsearch", "is"], "boolean",
{ {
short_help: "Show where the search pattern matches as it is typed", shortHelp: "Show where the search pattern matches as it is typed",
help: "NOTE: Incremental searching currently only works in the forward direction.", help: "NOTE: Incremental searching currently only works in the forward direction.",
default_value: true defaultValue: true
} }
)); ));
this.add(new vimperator.Option(["laststatus", "ls"], "number", optionManager.add(new vimperator.Option(["laststatus", "ls"], "number",
{ {
short_help: "Show the status line", shortHelp: "Show the status line",
help: "Determines when the last window will have a status line. " + help: "Determines when the last window will have a status line. " +
"Possible values:<br/>" + "Possible values:<br/>" +
"<ul>" + "<ul>" +
@@ -559,35 +563,35 @@ vimperator.Options = function () //{{{
"<li><b>2</b>: always</li>" + "<li><b>2</b>: always</li>" +
"</ul>" + "</ul>" +
"NOTE: laststatus=1 not implemented yet.", "NOTE: laststatus=1 not implemented yet.",
default_value: 2, defaultValue: 2,
setter: function (value) { setLastStatus(value); }, setter: function (value) { setLastStatus(value); },
validator: function (value) { return (value >= 0 && value <= 2); } validator: function (value) { return (value >= 0 && value <= 2); }
} }
)); ));
this.add(new vimperator.Option(["linksearch", "lks"], "boolean", optionManager.add(new vimperator.Option(["linksearch", "lks"], "boolean",
{ {
short_help: "Limit the search to hyperlink text", shortHelp: "Limit the search to hyperlink text",
help: "This includes (X)HTML elements with an \"href\" atrribute and XLink \"simple\" links.", help: "This includes (X)HTML elements with an \"href\" atrribute and XLink \"simple\" links.",
default_value: false defaultValue: false
} }
)); ));
this.add(new vimperator.Option(["more"], "boolean", optionManager.add(new vimperator.Option(["more"], "boolean",
{ {
short_help: "Pause the message list window when more than one screen of listings is displayed", shortHelp: "Pause the message list window when more than one screen of listings is displayed",
default_value: true defaultValue: true
} }
)); ));
this.add(new vimperator.Option(["maxhints", "mh"], "number", optionManager.add(new vimperator.Option(["maxhints", "mh"], "number",
{ {
short_help: "Maximum number of simultaneously shown hints", shortHelp: "Maximum number of simultaneously shown hints",
help: "If you want to speed up display of hints, choose a smaller value", help: "If you want to speed up display of hints, choose a smaller value",
default_value: 250, defaultValue: 250,
validator: function (value) { if (value >= 1 && value <= 1000) return true; else return false; } validator: function (value) { if (value >= 1 && value <= 1000) return true; else return false; }
} }
)); ));
this.add(new vimperator.Option(["pageinfo", "pa"], "charlist", optionManager.add(new vimperator.Option(["pageinfo", "pa"], "charlist",
{ {
short_help: "Desired info on :pa[geinfo]", shortHelp: "Desired info on :pa[geinfo]",
help: "Available items:<br/>" + help: "Available items:<br/>" +
"<ul>" + "<ul>" +
"<li><b>g</b>: general info</li>" + "<li><b>g</b>: general info</li>" +
@@ -595,13 +599,13 @@ vimperator.Options = function () //{{{
"<li><b>m</b>: meta tags</li>" + "<li><b>m</b>: meta tags</li>" +
"</ul>" + "</ul>" +
"The order matters", "The order matters",
default_value: "gfm", defaultValue: "gfm",
validator: function (value) { return !(/[^gfm]/.test(value) || value.length > 3 || value.length < 1) } validator: function (value) { return !(/[^gfm]/.test(value) || value.length > 3 || value.length < 1); }
} }
)); ));
this.add(new vimperator.Option(["popups", "pps"], "number", optionManager.add(new vimperator.Option(["popups", "pps"], "number",
{ {
short_help: "Where to show requested popup windows", shortHelp: "Where to show requested popup windows",
help: "Define where to show requested popup windows. Does not apply to windows which are opened by middle clicking a link, they always open in a new tab. " + help: "Define where to show requested popup windows. Does not apply to windows which are opened by middle clicking a link, they always open in a new tab. " +
"Possible values:<br/>" + "Possible values:<br/>" +
"<ul>" + "<ul>" +
@@ -611,48 +615,48 @@ vimperator.Options = function () //{{{
"<li><b>3</b>: Always open in a new window</li>" + "<li><b>3</b>: Always open in a new window</li>" +
"</ul>" + "</ul>" +
"NOTE: This option does not change the popup blocker of Firefox in any way.", "NOTE: This option does not change the popup blocker of Firefox in any way.",
default_value: 1, defaultValue: 1,
setter: function (value) { setPopups(value); }, setter: function (value) { setPopups(value); },
validator: function (value) { return (value >= 0 && value <= 3); } validator: function (value) { return (value >= 0 && value <= 3); }
} }
)); ));
this.add(new vimperator.Option(["preload"], "boolean", optionManager.add(new vimperator.Option(["preload"], "boolean",
{ {
short_help: "Speed up first time history/bookmark completion", shortHelp: "Speed up first time history/bookmark completion",
help: "History access can be quite slow for a large history. Vimperator maintains a cache to speed it up significantly on subsequent access.<br/>" + help: "History access can be quite slow for a large history. Vimperator maintains a cache to speed it up significantly on subsequent access.<br/>" +
"In order to also speed up first time access, it is cached at startup, if this option is set (recommended).", "In order to also speed up first time access, it is cached at startup, if this option is set (recommended).",
default_value: true defaultValue: true
} }
)); ));
this.add(new vimperator.Option(["previewheight", "pvh"], "number", optionManager.add(new vimperator.Option(["previewheight", "pvh"], "number",
{ {
short_help: "Default height for preview window", shortHelp: "Default height for preview window",
help: "Value must be between 1 and 50. If the value is too high, completions may cover the command-line. " + help: "Value must be between 1 and 50. If the value is too high, completions may cover the command-line. " +
"Close the preview window with <code class=\"command\">:pclose</code>.<br/>" + "Close the preview window with <code class=\"command\">:pclose</code>.<br/>" +
"NOTE: Option currently disabled", "NOTE: Option currently disabled",
default_value: 10, defaultValue: 10,
validator: function (value) { return (value >= 1 && value <= 50); } validator: function (value) { return (value >= 1 && value <= 50); }
} }
)); ));
this.add(new vimperator.Option(["scroll", "scr"], "number", optionManager.add(new vimperator.Option(["scroll", "scr"], "number",
{ {
short_help: "Number of lines to scroll with <code class=\"mapping\">C-u</code> and <code class=\"mapping\">C-d</code> commands", shortHelp: "Number of lines to scroll with <code class=\"mapping\">C-u</code> and <code class=\"mapping\">C-d</code> commands",
help: "The number of lines scrolled defaults to half the window size. " + help: "The number of lines scrolled defaults to half the window size. " +
"When a <code class=\"argument\">{count}</code> is specified to the <code class=\"mapping\">&lt;C-u&gt;</code> or <code class=\"mapping\">&lt;C-d&gt;</code> commands this is used to set the value of <code class=\"option\">'scroll'</code> and also used for the current command. " + "When a <code class=\"argument\">{count}</code> is specified to the <code class=\"mapping\">&lt;C-u&gt;</code> or <code class=\"mapping\">&lt;C-d&gt;</code> commands this is used to set the value of <code class=\"option\">'scroll'</code> and also used for the current command. " +
"The value can be reset to half the window height with <code class=\"command\">:set scroll=0</code>.", "The value can be reset to half the window height with <code class=\"command\">:set scroll=0</code>.",
default_value: 0, defaultValue: 0,
validator: function (value) { return value >= 0; } validator: function (value) { return value >= 0; }
} }
)); ));
this.add(new vimperator.Option(["showmode", "smd"], "boolean", optionManager.add(new vimperator.Option(["showmode", "smd"], "boolean",
{ {
short_help: "Show the current mode in the command line", shortHelp: "Show the current mode in the command line",
default_value: true defaultValue: true
} }
)); ));
this.add(new vimperator.Option(["showstatuslinks", "ssli"], "number", optionManager.add(new vimperator.Option(["showstatuslinks", "ssli"], "number",
{ {
short_help: "Show the destination of the link under the cursor in the status bar", shortHelp: "Show the destination of the link under the cursor in the status bar",
help: "Also links which are focused by keyboard commands like <code class=\"mapping\">&lt;Tab&gt;</code> are shown. " + help: "Also links which are focused by keyboard commands like <code class=\"mapping\">&lt;Tab&gt;</code> are shown. " +
"Possible values:<br/>" + "Possible values:<br/>" +
"<ul>" + "<ul>" +
@@ -660,13 +664,13 @@ vimperator.Options = function () //{{{
"<li><b>1</b>: Show the link in the status line</li>" + "<li><b>1</b>: Show the link in the status line</li>" +
"<li><b>2</b>: Show the link in the command line</li>" + "<li><b>2</b>: Show the link in the command line</li>" +
"</ul>", "</ul>",
default_value: 1, defaultValue: 1,
validator: function (value) { return (value >= 0 && value <= 2); } validator: function (value) { return (value >= 0 && value <= 2); }
} }
)); ));
this.add(new vimperator.Option(["showtabline", "stal"], "number", optionManager.add(new vimperator.Option(["showtabline", "stal"], "number",
{ {
short_help: "Control when to show the tab bar of opened web pages", shortHelp: "Control when to show the tab bar of opened web pages",
help: "Possible values:<br/>" + help: "Possible values:<br/>" +
"<ul>" + "<ul>" +
"<li><b>0</b>: Never show tab bar</li>" + "<li><b>0</b>: Never show tab bar</li>" +
@@ -674,63 +678,63 @@ vimperator.Options = function () //{{{
"<li><b>2</b>: Always show tab bar</li>" + "<li><b>2</b>: Always show tab bar</li>" +
"</ul>", "</ul>",
setter: function (value) { setShowTabline(value); }, setter: function (value) { setShowTabline(value); },
default_value: 2, defaultValue: 2,
validator: function (value) { return (value >= 0 && value <= 2); } validator: function (value) { return (value >= 0 && value <= 2); }
} }
)); ));
this.add(new vimperator.Option(["smartcase", "scs"], "boolean", optionManager.add(new vimperator.Option(["smartcase", "scs"], "boolean",
{ {
short_help: "Override the 'ignorecase' option if the pattern contains uppercase characters", shortHelp: "Override the 'ignorecase' option if the pattern contains uppercase characters",
help: "This is only used if the <code class=\"option\">'ignorecase'</code> option is set.", help: "This is only used if the <code class=\"option\">'ignorecase'</code> option is set.",
default_value: true defaultValue: true
} }
)); ));
this.add(new vimperator.Option(["titlestring"], "string", optionManager.add(new vimperator.Option(["titlestring"], "string",
{ {
short_help: "Change the title of the browser window", shortHelp: "Change the title of the browser window",
help: "Vimperator changes the browser title from \"Title of web page - Mozilla Firefox\" to " + help: "Vimperator changes the browser title from \"Title of web page - Mozilla Firefox\" to " +
"\"Title of web page - Vimperator\".<br/>If you don't like that, you can restore it with: " + "\"Title of web page - Vimperator\".<br/>If you don't like that, you can restore it with: " +
"<code class=\"command\">:set titlestring=Mozilla Firefox</code>.", "<code class=\"command\">:set titlestring=Mozilla Firefox</code>.",
setter: function (value) { setTitleString(value); }, setter: function (value) { setTitleString(value); },
default_value: "Vimperator" defaultValue: "Vimperator"
} }
)); ));
this.add(new vimperator.Option(["usermode", "um"], "boolean", optionManager.add(new vimperator.Option(["usermode", "um"], "boolean",
{ {
short_help: "Show current website with a minimal style sheet to make it easily accessible", shortHelp: "Show current website with a minimal style sheet to make it easily accessible",
help: "Note that this is a local option for now, later it may be split into a global and <code class=\"command\">:setlocal</code> part", help: "Note that this is a local option for now, later it may be split into a global and <code class=\"command\">:setlocal</code> part",
setter: function (value) { getMarkupDocumentViewer().authorStyleDisabled = value; }, setter: function (value) { getMarkupDocumentViewer().authorStyleDisabled = value; },
getter: function () { return getMarkupDocumentViewer().authorStyleDisabled; }, getter: function () { return getMarkupDocumentViewer().authorStyleDisabled; },
default_value: false defaultValue: false
} }
)); ));
this.add(new vimperator.Option(["verbose", "vbs"], "number", optionManager.add(new vimperator.Option(["verbose", "vbs"], "number",
{ {
short_help: "Define which type of messages are logged", shortHelp: "Define which type of messages are logged",
help: "When bigger than zero, Vimperator will give messages about what it is doing. They are printed to the error console which can be shown with <code class=\"command\">:javascript!</code>.<br/>" + help: "When bigger than zero, Vimperator will give messages about what it is doing. They are printed to the error console which can be shown with <code class=\"command\">:javascript!</code>.<br/>" +
"The highest value is 9, being the most verbose mode.", "The highest value is 9, being the most verbose mode.",
default_value: 0, defaultValue: 0,
validator: function (value) { return (value >= 0 && value <= 9); } validator: function (value) { return (value >= 0 && value <= 9); }
} }
)); ));
this.add(new vimperator.Option(["visualbell", "vb"], "boolean", optionManager.add(new vimperator.Option(["visualbell", "vb"], "boolean",
{ {
short_help: "Use visual bell instead of beeping on errors", shortHelp: "Use visual bell instead of beeping on errors",
setter: function (value) { vimperator.options.setFirefoxPref("accessibility.typeaheadfind.enablesound", !value); }, setter: function (value) { vimperator.options.setFirefoxPref("accessibility.typeaheadfind.enablesound", !value); },
default_value: false defaultValue: false
} }
)); ));
this.add(new vimperator.Option(["visualbellstyle", "t_vb"], "string", optionManager.add(new vimperator.Option(["visualbellstyle", "t_vb"], "string",
{ {
short_help: "CSS specification of the visual bell", shortHelp: "CSS specification of the visual bell",
help: "To hide the visual bell use a value of \"display: none;\" or unset it with <code class=\"command\">:set t_vb=</code>", help: "To hide the visual bell use a value of \"display: none;\" or unset it with <code class=\"command\">:set t_vb=</code>",
setter: function (value) { if (!value) value = "display: none;"; }, setter: function (value) { if (!value) value = "display: none;"; },
default_value: "background-color: black; color: black;" defaultValue: "background-color: black; color: black;"
} }
)); ));
this.add(new vimperator.Option(["wildmode", "wim"], "stringlist", optionManager.add(new vimperator.Option(["wildmode", "wim"], "stringlist",
{ {
short_help: "Define how command line completion works", shortHelp: "Define how command line completion works",
help: "It is a comma-separated list of parts, where each part specifies " + help: "It is a comma-separated list of parts, where each part specifies " +
"what to do for each consecutive use of the completion key. The first part " + "what to do for each consecutive use of the completion key. The first part " +
"specifies the behavior for the first use of the completion key, the second part " + "specifies the behavior for the first use of the completion key, the second part " +
@@ -745,22 +749,22 @@ vimperator.Options = function () //{{{
"<tr><td><b>'list:longest'</b></td><td>When more than one match, list all matches and complete till the longest common string.</td></tr>" + "<tr><td><b>'list:longest'</b></td><td>When more than one match, list all matches and complete till the longest common string.</td></tr>" +
"</table>" + "</table>" +
"When there is only a single match, it is fully completed regardless of the case.", "When there is only a single match, it is fully completed regardless of the case.",
default_value: "list:full", defaultValue: "list:full",
validator: function (value) validator: function (value)
{ {
return value.split(",").every(function (item) { return /^(full|longest|list|list:full|list:longest|)$/.test(item); }); return value.split(",").every(function (item) { return /^(full|longest|list|list:full|list:longest|)$/.test(item); });
} }
} }
)); ));
this.add(new vimperator.Option(["wildoptions", "wop"], "stringlist", optionManager.add(new vimperator.Option(["wildoptions", "wop"], "stringlist",
{ {
short_help: "Change how command line completion is done", shortHelp: "Change how command line completion is done",
help: "A list of words that change how command line completion is done.<br/>" + help: "A list of words that change how command line completion is done.<br/>" +
"Currently only one word is allowed:<br/>" + "Currently only one word is allowed:<br/>" +
"<table>" + "<table>" +
"<tr><td><b>sort</b></td><td>Always sorts completion list, overriding the <code class=\"option\">'complete'</code> option.</td></tr>" + "<tr><td><b>sort</b></td><td>Always sorts completion list, overriding the <code class=\"option\">'complete'</code> option.</td></tr>" +
"</table>", "</table>",
default_value: "", defaultValue: "",
validator: function (value) { return /^(sort|)$/.test(value); } validator: function (value) { return /^(sort|)$/.test(value); }
} }
)); ));
@@ -771,10 +775,12 @@ vimperator.Options = function () //{{{
setShowTabline(0); setShowTabline(0);
setGuiOptions(""); setGuiOptions("");
setLastStatus(0); setLastStatus(0);
guioptions_done = showtabline_done = laststatus_done = false; guioptionsDone = showtablineDone = laststatusDone = false;
setTitleString(this.titlestring); setTitleString(optionManager.titlestring);
setPopups(this.popups); setPopups(optionManager.popups);
} //}}}
return optionManager;
}; //}}}
// vim: set fdm=marker sw=4 ts=4 et: // vim: set fdm=marker sw=4 ts=4 et:

View File

@@ -38,13 +38,12 @@ vimperator.Tabs = function () //{{{
////////////////////// PRIVATE SECTION ///////////////////////////////////////// ////////////////////// PRIVATE SECTION /////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
/** @param spec can either be: // @param spec can either be:
* - an absolute integer // - an absolute integer
* - "" for the current tab // - "" for the current tab
* - "+1" for the next tab // - "+1" for the next tab
* - "-3" for the tab, which is 3 positions left of the current // - "-3" for the tab, which is 3 positions left of the current
* - "$" for the last tab // - "$" for the last tab
*/
function indexFromSpec(spec, wrap) function indexFromSpec(spec, wrap)
{ {
var position = getBrowser().tabContainer.selectedIndex; var position = getBrowser().tabContainer.selectedIndex;
@@ -58,7 +57,7 @@ vimperator.Tabs = function () //{{{
position = spec; position = spec;
else if (spec === "$") else if (spec === "$")
return last; return last;
else if (!spec.match(/^([+-]?\d+|)$/)) else if (!/^([+-]?\d+|)$/.test(spec))
{ {
// TODO: move error reporting to ex-command? // TODO: move error reporting to ex-command?
vimperator.echoerr("E488: Trailing characters"); vimperator.echoerr("E488: Trailing characters");
@@ -66,7 +65,7 @@ vimperator.Tabs = function () //{{{
} }
else else
{ {
if (spec.match(/^([+-]\d+)$/)) // relative position +/-N if (/^([+-]\d+)$/.test(spec)) // relative position +/-N
position += parseInt(spec, 10); position += parseInt(spec, 10);
else // absolute position else // absolute position
position = parseInt(spec, 10); position = parseInt(spec, 10);
@@ -80,195 +79,192 @@ vimperator.Tabs = function () //{{{
return position; return position;
} }
var alternates = [null, null]; var alternates = [getBrowser().mCurrentTab, null];
/////////////////////////////////////////////////////////////////////////////}}} /////////////////////////////////////////////////////////////////////////////}}}
////////////////////// PUBLIC SECTION ////////////////////////////////////////// ////////////////////// PUBLIC SECTION //////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
// @returns the index of the currently selected tab starting with 0 return {
this.index = function (tab)
{ get alternate() { return alternates[1]; },
if (tab)
get count() { return getBrowser().mTabs.length; },
// @returns the index of the currently selected tab starting with 0
index: function (tab)
{ {
var length = getBrowser().mTabs.length; if (tab)
for (var i = 0; i < length; i++)
{ {
if (getBrowser().mTabs[i] == tab) var length = getBrowser().mTabs.length;
return i; for (var i = 0; i < length; i++)
}
return -1;
}
return getBrowser().tabContainer.selectedIndex;
}
this.count = function ()
{
return getBrowser().mTabs.length;
}
// TODO: implement filter
// @returns an array of tabs which match filter
this.get = function (filter)
{
var buffers = [];
var browsers = getBrowser().browsers;
for (var i in browsers)
{
var title = browsers[i].contentTitle || "(Untitled)";
var uri = browsers[i].currentURI.spec;
var number = i + 1;
buffers.push([number, title, uri]);
}
return buffers;
}
this.getTab = function (index)
{
if (index)
return getBrowser().mTabs[index];
return getBrowser().tabContainer.selectedItem;
}
/* spec == "" moves the tab to the last position as per Vim
* wrap causes the movement to wrap around the start and end of the tab list
* NOTE: position is a 0 based index
* FIXME: tabmove! N should probably produce an error
*/
this.move = function (tab, spec, wrap)
{
if (spec === "")
spec = "$"; // if not specified, move to the last tab -> XXX: move to ex handling?
var index = indexFromSpec(spec, wrap);
getBrowser().moveTabTo(tab, index);
}
/* quit_on_last_tab = 1: quit without saving session
* quit_on_last_tab = 2: quit and save session
*/
this.remove = function (tab, count, focus_left_tab, quit_on_last_tab)
{
function removeOrBlankTab (tab)
{
if (getBrowser().mTabs.length > 1)
getBrowser().removeTab(tab);
else
{
if (vimperator.buffer.URL != "about:blank" ||
getWebNavigation().sessionHistory.count > 0)
{ {
vimperator.open("about:blank", vimperator.NEW_BACKGROUND_TAB); if (getBrowser().mTabs[i] == tab)
return i;
}
return -1;
}
return getBrowser().tabContainer.selectedIndex;
},
// TODO: implement filter
// @returns an array of tabs which match filter
get: function (filter)
{
var buffers = [];
var browsers = getBrowser().browsers;
for (var i in browsers)
{
var title = browsers[i].contentTitle || "(Untitled)";
var uri = browsers[i].currentURI.spec;
var number = i + 1;
buffers.push([number, title, uri]);
}
return buffers;
},
getTab: function (index)
{
if (index)
return getBrowser().mTabs[index];
return getBrowser().tabContainer.selectedItem;
},
// spec == "" moves the tab to the last position as per Vim
// wrap causes the movement to wrap around the start and end of the tab list
// NOTE: position is a 0 based index
// FIXME: tabmove! N should probably produce an error
move: function (tab, spec, wrap)
{
if (spec === "")
spec = "$"; // if not specified, move to the last tab -> XXX: move to ex handling?
var index = indexFromSpec(spec, wrap);
getBrowser().moveTabTo(tab, index);
},
// quitOnLastTab = 1: quit without saving session
// quitOnLastTab = 2: quit and save session
remove: function (tab, count, focusLeftTab, quitOnLastTab)
{
function removeOrBlankTab (tab)
{
if (getBrowser().mTabs.length > 1)
getBrowser().removeTab(tab); getBrowser().removeTab(tab);
}
else else
vimperator.beep(); {
if (vimperator.buffer.URL != "about:blank" ||
getWebNavigation().sessionHistory.count > 0)
{
vimperator.open("about:blank", vimperator.NEW_BACKGROUND_TAB);
getBrowser().removeTab(tab);
}
else
vimperator.beep();
}
} }
}
if (count < 1) if (count < 1)
count = 1; count = 1;
if (quit_on_last_tab >= 1 && getBrowser().mTabs.length <= count) if (quitOnLastTab >= 1 && getBrowser().mTabs.length <= count)
{ {
if (vimperator.windows.length > 1) if (vimperator.windows.length > 1)
window.close(); window.close();
else
vimperator.quit(quitOnLastTab == 2);
return;
}
var index = this.index(tab);
if (focusLeftTab)
{
var lastRemovedTab = 0;
for (var i = index; i > index - count && i >= 0; i--)
{
removeOrBlankTab(this.getTab(i));
lastRemovedTab = i > 0 ? i : 1;
}
getBrowser().mTabContainer.selectedIndex = lastRemovedTab - 1;
}
else else
vimperator.quit(quit_on_last_tab == 2);
return;
}
var index = this.index(tab);
if (focus_left_tab)
{
var last_removed_tab = 0;
for (var i = index; i > index - count && i >= 0; i--)
{ {
removeOrBlankTab(this.getTab(i)); var i = index + count - 1;
last_removed_tab = i > 0 ? i : 1; if (i >= this.count)
i = this.count - 1;
for (; i >= index; i--)
removeOrBlankTab(this.getTab(i));
} }
getBrowser().mTabContainer.selectedIndex = last_removed_tab - 1; },
}
else keepOnly: function (tab)
{ {
var i = index + count - 1; getBrowser().removeAllTabsBut(tab);
if (i >= this.count()) },
i = this.count() - 1;
for (; i >= index; i--) select: function (spec, wrap)
removeOrBlankTab(this.getTab(i));
}
}
this.keepOnly = function (tab)
{
getBrowser().removeAllTabsBut(tab);
}
this.select = function (spec, wrap)
{
var index = indexFromSpec(spec, wrap);
if (index === false)
{ {
vimperator.beep(); // XXX: move to ex-handling? var index = indexFromSpec(spec, wrap);
return false; if (index === false)
}
getBrowser().mTabContainer.selectedIndex = index;
}
// TODO: when restarting a session FF selects the first tab and then the
// tab that was selected when the session was created. As a result the
// alternate after a restart is often incorrectly tab 1 when there
// shouldn't be one yet.
this.updateSelectionHistory = function ()
{
alternates = [this.getTab(), alternates[0]];
this.alternate = alternates[1];
}
// TODO: move to v.buffers
this.alternate = this.getTab();
this.reload = function (tab, bypass_cache)
{
if (bypass_cache)
{
const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
const flags = nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY | nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE;
getBrowser().getBrowserForTab(tab).reloadWithFlags(flags);
}
else
{
getBrowser().reloadTab(tab);
}
}
this.reloadAll = function (bypass_cache)
{
if (bypass_cache)
{
for (var i = 0; i < getBrowser().mTabs.length; i++)
{ {
try vimperator.beep(); // XXX: move to ex-handling?
return false;
}
getBrowser().mTabContainer.selectedIndex = index;
},
// TODO: when restarting a session FF selects the first tab and then the
// tab that was selected when the session was created. As a result the
// alternate after a restart is often incorrectly tab 1 when there
// shouldn't be one yet.
updateSelectionHistory: function ()
{
alternates = [this.getTab(), alternates[0]];
},
reload: function (tab, bypassCache)
{
if (bypassCache)
{
const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
const flags = nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY | nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE;
getBrowser().getBrowserForTab(tab).reloadWithFlags(flags);
}
else
{
getBrowser().reloadTab(tab);
}
},
reloadAll: function (bypassCache)
{
if (bypassCache)
{
for (var i = 0; i < getBrowser().mTabs.length; i++)
{ {
this.reload(getBrowser().mTabs[i], bypass_cache) try
} {
catch (e) this.reload(getBrowser().mTabs[i], bypassCache);
{ }
// FIXME: can we do anything useful here without stopping the catch (e)
// other tabs from reloading? {
// FIXME: can we do anything useful here without stopping the
// other tabs from reloading?
}
} }
} }
else
{
getBrowser().reloadAllTabs();
}
} }
else
{ };
getBrowser().reloadAllTabs();
}
}
//}}} //}}}
} //}}} }; //}}}
// vim: set fdm=marker sw=4 ts=4 et: // vim: set fdm=marker sw=4 ts=4 et:

File diff suppressed because it is too large Load Diff

View File

@@ -26,7 +26,8 @@ the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL. the terms of any one of the MPL, the GPL or the LGPL.
}}} ***** END LICENSE BLOCK *****/ }}} ***** END LICENSE BLOCK *****/
vimperator.util = { vimperator.util = { //{{{
escapeHTML: function (str) escapeHTML: function (str)
{ {
// XXX: the following code is _much_ slower than a simple .replace() // XXX: the following code is _much_ slower than a simple .replace()
@@ -39,11 +40,11 @@ vimperator.util = {
}, },
// TODO: use :highlight color groups // TODO: use :highlight color groups
// if "process_strings" is true, any passed strings will be surrounded by " and // if "processStrings" is true, any passed strings will be surrounded by " and
// any line breaks are displayed as \n // any line breaks are displayed as \n
colorize: function (arg, process_strings) colorize: function (arg, processStrings)
{ {
var type = typeof(arg); var type = typeof arg;
// some objects like window.JSON or getBrowsers()._browsers need the try/catch // some objects like window.JSON or getBrowsers()._browsers need the try/catch
try try
@@ -54,7 +55,7 @@ vimperator.util = {
} }
else if (type == "string") else if (type == "string")
{ {
if (process_strings) if (processStrings)
arg = '"' + vimperator.util.escapeHTML(arg.replace(/\n/, "\\n")) + '"'; arg = '"' + vimperator.util.escapeHTML(arg.replace(/\n/, "\\n")) + '"';
return "<span style=\"color: green;\">" + arg + "</span>"; return "<span style=\"color: green;\">" + arg + "</span>";
@@ -97,7 +98,7 @@ vimperator.util = {
begin: for (var url = 0; url < urls.length; url++) begin: for (var url = 0; url < urls.length; url++)
{ {
var new_url = vimperator.buffer.URL; var newURL = vimperator.buffer.URL;
var matches; var matches;
// strip each 'URL' - makes things simpler later on // strip each 'URL' - makes things simpler later on
@@ -108,13 +109,13 @@ vimperator.util = {
if (matches = urls[url].match(/^(?:\.$|\.\/(\S*))/)) if (matches = urls[url].match(/^(?:\.$|\.\/(\S*))/))
{ {
var tail = matches[1] || ""; var tail = matches[1] || "";
urls[url] = new_url.replace(/(.+\/)[^\/]*/, "$1" + tail); // NOTE: escape / in character sets so as not to break Vim syntax highlighting urls[url] = newURL.replace(/(.+\/)[^\/]*/, "$1" + tail); // NOTE: escape / in character sets so as not to break Vim syntax highlighting
continue; continue;
} }
else if (matches = urls[url].match(/^(?:\.\.$|\.\.\/(\S*))/)) else if (matches = urls[url].match(/^(?:\.\.$|\.\.\/(\S*))/))
{ {
var tail = matches[1] || ""; var tail = matches[1] || "";
urls[url] = new_url.replace(/(.+\/)[^\/]*/, "$1../" + tail); urls[url] = newURL.replace(/(.+\/)[^\/]*/, "$1../" + tail);
continue; continue;
} }
else if (matches = urls[url].match(/^(?:\.\.\.$|\.\.\.\/(\S*))/)) else if (matches = urls[url].match(/^(?:\.\.\.$|\.\.\.\/(\S*))/))
@@ -142,18 +143,18 @@ vimperator.util = {
// like the comments below ;-) // like the comments below ;-)
// check if the first word is a search engine // check if the first word is a search engine
var search_url = vimperator.bookmarks.getSearchURL(text, alias); var searchURL = vimperator.bookmarks.getSearchURL(text, alias);
if (search_url/* && search_url.length >= 1*/) if (searchURL/* && searchURL.length >= 1*/)
{ {
urls[url] = search_url; urls[url] = searchURL;
continue; continue;
} }
else // the first word was not a search engine, search for the whole string in the default engine else // the first word was not a search engine, search for the whole string in the default engine
{ {
search_url = vimperator.bookmarks.getSearchURL(urls[url], null); searchURL = vimperator.bookmarks.getSearchURL(urls[url], null);
if (search_url/* && search_url.length >= 1*/) if (searchURL/* && searchURL.length >= 1*/)
{ {
urls[url] = search_url; urls[url] = searchURL;
continue; continue;
} }
} }
@@ -206,6 +207,7 @@ vimperator.util = {
return strNum[0] + " " + unitVal[unitIndex]; return strNum[0] + " " + unitVal[unitIndex];
} }
};
}; //}}}
// vim: set fdm=marker sw=4 ts=4 et: // vim: set fdm=marker sw=4 ts=4 et:

View File

@@ -52,32 +52,32 @@ const vimperator = (function () //{{{
EXTENDED_HINT: 1 << 18, EXTENDED_HINT: 1 << 18,
ALWAYS_HINT: 1 << 19, ALWAYS_HINT: 1 << 19,
MENU: 1 << 20 // a popupmenu is active MENU: 1 << 20 // a popupmenu is active
} };
var mode_messages = {}; var modeMessages = {};
mode_messages[modes.NORMAL] = ""; modeMessages[modes.NORMAL] = "";
mode_messages[modes.INSERT] = "INSERT"; modeMessages[modes.INSERT] = "INSERT";
mode_messages[modes.VISUAL] = "VISUAL"; modeMessages[modes.VISUAL] = "VISUAL";
mode_messages[modes.HINTS] = "HINTS"; modeMessages[modes.HINTS] = "HINTS";
mode_messages[modes.ESCAPE_ONE_KEY] = "escape one key"; modeMessages[modes.ESCAPE_ONE_KEY] = "escape one key";
mode_messages[modes.ESCAPE_ALL_KEYS] = "escape all keys"; modeMessages[modes.ESCAPE_ALL_KEYS] = "escape all keys";
mode_messages[modes.ESCAPE_ONE_KEY | modes.ESCAPE_ALL_KEYS] = "pass one key"; modeMessages[modes.ESCAPE_ONE_KEY | modes.ESCAPE_ALL_KEYS] = "pass one key";
mode_messages[modes.QUICK_HINT] = "quick"; modeMessages[modes.QUICK_HINT] = "quick";
mode_messages[modes.EXTENDED_HINT] = "extended"; modeMessages[modes.EXTENDED_HINT] = "extended";
mode_messages[modes.ALWAYS_HINT] = "always"; modeMessages[modes.ALWAYS_HINT] = "always";
//mode_messages[modes.MENU] = "menu"; // not a user visible mode //modeMessages[modes.MENU] = "menu"; // not a user visible mode
var mode = modes.NORMAL; var mode = modes.NORMAL;
var extended_mode = modes.NONE; var extendedMode = modes.NONE;
var callbacks = []; var callbacks = [];
// our services // our services
var sound_service = Components.classes["@mozilla.org/sound;1"] var soundService = Components.classes["@mozilla.org/sound;1"]
.getService(Components.interfaces.nsISound); .getService(Components.interfaces.nsISound);
var console_service = Components.classes["@mozilla.org/consoleservice;1"] var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
.getService(Components.interfaces.nsIConsoleService); .getService(Components.interfaces.nsIConsoleService);
var environment_service = Components.classes["@mozilla.org/process/environment;1"] var environmentService = Components.classes["@mozilla.org/process/environment;1"]
.getService(Components.interfaces.nsIEnvironment); .getService(Components.interfaces.nsIEnvironment);
function showMode() function showMode()
@@ -85,23 +85,23 @@ const vimperator = (function () //{{{
if (!vimperator.options["showmode"]) if (!vimperator.options["showmode"])
return; return;
var str_mode = mode_messages[mode]; var strMode = modeMessages[mode];
var str_extended = mode_messages[extended_mode]; var strExtended = modeMessages[extendedMode];
if (!str_mode && !str_extended) if (!strMode && !strExtended)
{ {
vimperator.echo(""); vimperator.echo("");
return; return;
} }
if (str_mode && str_extended) if (strMode && strExtended)
str_extended = " (" + str_extended + ")"; strExtended = " (" + strExtended + ")";
else else
{ {
str_extended = "(" + str_extended + ")"; strExtended = "(" + strExtended + ")";
str_mode = ""; strMode = "";
} }
vimperator.echo("-- " + str_mode + str_extended + " --"); vimperator.echo("-- " + strMode + strExtended + " --");
} }
/////////////////////////////////////////////////////////////////////////////}}} /////////////////////////////////////////////////////////////////////////////}}}
@@ -154,7 +154,7 @@ const vimperator = (function () //{{{
getMode: function () getMode: function ()
{ {
return [mode, extended_mode]; return [mode, extendedMode];
}, },
// set current mode // set current mode
@@ -165,10 +165,10 @@ const vimperator = (function () //{{{
if (main) if (main)
{ {
mode = main; mode = main;
extended_mode = vimperator.modes.NONE; extendedMode = vimperator.modes.NONE;
} }
if (typeof extended === "number") if (typeof extended === "number")
extended_mode = extended; extendedMode = extended;
if (!silent) if (!silent)
showMode(); showMode();
@@ -178,7 +178,7 @@ const vimperator = (function () //{{{
// extended mode // extended mode
hasMode: function (whichmode) hasMode: function (whichmode)
{ {
return ((mode & whichmode) || (extended_mode & whichmode) > 0) ? true : false; return ((mode & whichmode) || (extendedMode & whichmode) > 0) ? true : false;
}, },
addMode: function (main, extended) addMode: function (main, extended)
@@ -186,7 +186,7 @@ const vimperator = (function () //{{{
if (main) if (main)
mode |= main; mode |= main;
if (extended) if (extended)
extended_mode |= extended; extendedMode |= extended;
showMode(); showMode();
}, },
@@ -197,7 +197,7 @@ const vimperator = (function () //{{{
if (main) if (main)
mode = (mode | main) ^ main; mode = (mode | main) ^ main;
if (extended) if (extended)
extended_mode = (extended_mode | extended) ^ extended; extendedMode = (extendedMode | extended) ^ extended;
showMode(); showMode();
}, },
@@ -217,13 +217,13 @@ const vimperator = (function () //{{{
vbell.style.left = box.x + "px"; vbell.style.left = box.x + "px";
vbell.style.top = box.y + "px"; vbell.style.top = box.y + "px";
vbell.hidden = false vbell.hidden = false;
setTimeout(function () { vbell.hidden = true; }, 50); // may as well be 0 ;-) setTimeout(function () { vbell.hidden = true; }, 50); // may as well be 0 ;-)
} }
else else
{ {
sound_service.beep(); soundService.beep();
} }
}, },
@@ -409,7 +409,7 @@ const vimperator = (function () //{{{
if (typeof msg == "object") if (typeof msg == "object")
msg = this.objectToString(msg, false); msg = this.objectToString(msg, false);
console_service.logStringMessage("vimperator: " + msg); consoleService.logStringMessage("vimperator: " + msg);
}, },
// open one or more URLs // open one or more URLs
@@ -482,9 +482,9 @@ const vimperator = (function () //{{{
}, },
// quit vimperator, no matter how many tabs/windows are open // quit vimperator, no matter how many tabs/windows are open
quit: function (save_session) quit: function (saveSession)
{ {
if (save_session) if (saveSession)
vimperator.options.setFirefoxPref("browser.startup.page", 3); // start with saved session vimperator.options.setFirefoxPref("browser.startup.page", 3); // start with saved session
else else
vimperator.options.setFirefoxPref("browser.startup.page", 1); // start with default homepage session vimperator.options.setFirefoxPref("browser.startup.page", 1); // start with default homepage session
@@ -532,7 +532,7 @@ const vimperator = (function () //{{{
if (!args) if (!args)
args = []; args = [];
if (typeof(blocking) != "boolean") if (typeof blocking != "boolean")
blocking = false; blocking = false;
try try
@@ -541,7 +541,7 @@ const vimperator = (function () //{{{
} }
catch (e) catch (e)
{ {
var dirs = environment_service.get("PATH").split(WINDOWS ? ";" : ":"); var dirs = environmentService.get("PATH").split(WINDOWS ? ";" : ":");
for (var i = 0; i < dirs.length; i++) for (var i = 0; i < dirs.length; i++)
{ {
var path = dirs[i] + (WINDOWS ? "\\" : "/") + program; var path = dirs[i] + (WINDOWS ? "\\" : "/") + program;
@@ -604,8 +604,8 @@ const vimperator = (function () //{{{
filein.remove(false); filein.remove(false);
// if there is only one \n at the end, chop it off // if there is only one \n at the end, chop it off
if (output && output.indexOf("\n") == output.length-1) if (output && output.indexOf("\n") == output.length - 1)
output = output.substr(0, output.length-1); output = output.substr(0, output.length - 1);
return output; return output;
}, },
@@ -628,16 +628,16 @@ const vimperator = (function () //{{{
else else
{ {
var heredoc = ""; var heredoc = "";
var heredoc_end = null; // the string which ends the heredoc var heredocEnd = null; // the string which ends the heredoc
str.split("\n").forEach(function (line) str.split("\n").forEach(function (line)
{ {
if (heredoc_end) // we already are in a heredoc if (heredocEnd) // we already are in a heredoc
{ {
if (heredoc_end.test(line)) if (heredocEnd.test(line))
{ {
eval(heredoc); eval(heredoc);
heredoc = ""; heredoc = "";
heredoc_end = null; heredocEnd = null;
} }
else else
{ {
@@ -654,7 +654,7 @@ const vimperator = (function () //{{{
var matches = args.match(/(.*)<<\s*([^\s]+)$/); var matches = args.match(/(.*)<<\s*([^\s]+)$/);
if (matches) if (matches)
{ {
heredoc_end = new RegExp("^" + matches[2] + "$", "m"); heredocEnd = new RegExp("^" + matches[2] + "$", "m");
if (matches[1]) if (matches[1])
heredoc = matches[1] + "\n"; heredoc = matches[1] + "\n";
} }
@@ -688,51 +688,51 @@ const vimperator = (function () //{{{
// these objects are created here only after the chrome is ready // these objects are created here only after the chrome is ready
vimperator.log("Loading module options...", 3); vimperator.log("Loading module options...", 3);
vimperator.options = new vimperator.Options(); vimperator.options = vimperator.Options();
vimperator.log("Loading module events...", 3); vimperator.log("Loading module events...", 3);
vimperator.events = new vimperator.Events(); vimperator.events = vimperator.Events();
vimperator.log("Loading module commands...", 3); vimperator.log("Loading module commands...", 3);
vimperator.commands = new vimperator.Commands(); vimperator.commands = vimperator.Commands();
vimperator.log("Loading module bookmarks...", 3); vimperator.log("Loading module bookmarks...", 3);
vimperator.bookmarks = new vimperator.Bookmarks(); vimperator.bookmarks = vimperator.Bookmarks();
vimperator.log("Loading module history...", 3); vimperator.log("Loading module history...", 3);
vimperator.history = new vimperator.History(); vimperator.history = vimperator.History();
vimperator.log("Loading module commandline...", 3); vimperator.log("Loading module commandline...", 3);
vimperator.commandline = new vimperator.CommandLine(); vimperator.commandline = vimperator.CommandLine();
vimperator.log("Loading module search...", 3); vimperator.log("Loading module search...", 3);
vimperator.search = new vimperator.Search(); vimperator.search = vimperator.Search();
vimperator.log("Loading module preview window...", 3); vimperator.log("Loading module preview window...", 3);
vimperator.previewwindow = new vimperator.InformationList("vimperator-previewwindow", { incremental_fill: false, max_items: 10 }); vimperator.previewwindow = vimperator.InformationList("vimperator-previewwindow", { incrementalFill: false, maxItems: 10 });
vimperator.log("Loading module buffer window...", 3); vimperator.log("Loading module buffer window...", 3);
vimperator.bufferwindow = new vimperator.InformationList("vimperator-bufferwindow", { incremental_fill: false, max_items: 10 }); vimperator.bufferwindow = vimperator.InformationList("vimperator-bufferwindow", { incrementalFill: false, maxItems: 10 });
vimperator.log("Loading module mappings...", 3); vimperator.log("Loading module mappings...", 3);
vimperator.mappings = new vimperator.Mappings(); vimperator.mappings = vimperator.Mappings();
vimperator.log("Loading module statusline...", 3); vimperator.log("Loading module statusline...", 3);
vimperator.statusline = new vimperator.StatusLine(); vimperator.statusline = vimperator.StatusLine();
vimperator.log("Loading module buffer...", 3); vimperator.log("Loading module buffer...", 3);
vimperator.buffer = new vimperator.Buffer(); vimperator.buffer = vimperator.Buffer();
vimperator.log("Loading module tabs...", 3); vimperator.log("Loading module tabs...", 3);
vimperator.tabs = new vimperator.Tabs(); vimperator.tabs = vimperator.Tabs();
vimperator.log("Loading module marks...", 3); vimperator.log("Loading module marks...", 3);
vimperator.marks = new vimperator.Marks(); vimperator.marks = vimperator.Marks();
vimperator.log("Loading module quickmarks...", 3); vimperator.log("Loading module quickmarks...", 3);
vimperator.quickmarks = new vimperator.QuickMarks(); vimperator.quickmarks = vimperator.QuickMarks();
vimperator.log("Loading module hints...", 3); vimperator.log("Loading module hints...", 3);
vimperator.hints = new vimperator.Hints(); vimperator.hints = vimperator.Hints();
vimperator.log("Loading module io...", 3); vimperator.log("Loading module io...", 3);
vimperator.io = new vimperator.IO(); vimperator.io = vimperator.IO();
vimperator.log("Loading module completion...", 3); vimperator.log("Loading module completion...", 3);
vimperator.completion = new vimperator.Completion(); vimperator.completion = vimperator.Completion();
vimperator.log("All modules loaded", 3); vimperator.log("All modules loaded", 3);
vimperator.echo = function (str) { vimperator.commandline.echo(str); } vimperator.echo = function (str, flags) { vimperator.commandline.echo(str, vimperator.commandline.HL_NORMAL, flags); };
vimperator.echoerr = function (str) { vimperator.commandline.echo(str, vimperator.commandline.HL_ERRORMSG); } vimperator.echoerr = function (str, flags) { vimperator.commandline.echo(str, vimperator.commandline.HL_ERRORMSG, flags); };
vimperator.globalVariables = {}; vimperator.globalVariables = {};
// TODO: move elsewhere // TODO: move elsewhere
vimperator.registerCallback("submit", vimperator.modes.EX, function (command) { vimperator.execute(command); } ); vimperator.registerCallback("submit", vimperator.modes.EX, function (command) { vimperator.execute(command); });
vimperator.registerCallback("complete", vimperator.modes.EX, function (str) { return vimperator.completion.exTabCompletion(str); } ); vimperator.registerCallback("complete", vimperator.modes.EX, function (str) { return vimperator.completion.exTabCompletion(str); });
// first time intro message // first time intro message
if (vimperator.options.getPref("firsttime", true)) if (vimperator.options.getPref("firsttime", true))
@@ -749,20 +749,20 @@ const vimperator = (function () //{{{
// make sourcing asynchronous, otherwise commands that open new tabs won't work // make sourcing asynchronous, otherwise commands that open new tabs won't work
setTimeout(function () { setTimeout(function () {
var rc_file = vimperator.io.getRCFile(); var rcFile = vimperator.io.getRCFile();
if (rc_file) if (rcFile)
vimperator.source(rc_file.path, true); vimperator.source(rcFile.path, true);
else else
vimperator.log("No user RC file found", 3); vimperator.log("No user RC file found", 3);
// also source plugins in ~/.vimperator/plugin/ // also source plugins in ~/.vimperator/plugin/
try try
{ {
var plugin_dir = vimperator.io.getPluginDir(); var pluginDir = vimperator.io.getPluginDir();
if (plugin_dir) if (pluginDir)
{ {
var files = vimperator.io.readDirectory(plugin_dir.path); var files = vimperator.io.readDirectory(pluginDir.path);
vimperator.log("Sourcing plugin directory...", 3); vimperator.log("Sourcing plugin directory...", 3);
files.forEach(function (file) { files.forEach(function (file) {
if (!file.isDirectory() && /\.js$/.test(file.path)) if (!file.isDirectory() && /\.js$/.test(file.path))
@@ -809,21 +809,22 @@ const vimperator = (function () //{{{
var mainThread = threadManager.mainThread; var mainThread = threadManager.mainThread;
var then = new Date().getTime(), now = then; var then = new Date().getTime(), now = then;
for (; now - then < ms; now = new Date().getTime()) { for (; now - then < ms; now = new Date().getTime())
mainThread.processNextEvent(true); mainThread.processNextEvent(true);
}
}, },
get windows() get windows()
{ {
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator); var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var wa = []; var wa = [];
var enumerator = wm.getEnumerator("navigator:browser"); var enumerator = wm.getEnumerator("navigator:browser");
while (enumerator.hasMoreElements()) while (enumerator.hasMoreElements())
wa.push(enumerator.getNext()); wa.push(enumerator.getNext());
return wa; return wa;
} }
} //}}}
}; //}}}
})(); //}}} })(); //}}}
// called when the chrome is fully loaded and before the main window is shown // called when the chrome is fully loaded and before the main window is shown