mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-21 23:27:58 +01:00
Initial import
This commit is contained in:
153
chrome/content/vimperator/bookmarks.js
Normal file
153
chrome/content/vimperator/bookmarks.js
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
* low-level BOOKMARK and HISTORY handling
|
||||||
|
*
|
||||||
|
* these commands try to be generic and don't use any GUI handling code
|
||||||
|
* for higher-level functions look into commands.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getProperty( aInput, aArc, DS )
|
||||||
|
{
|
||||||
|
var node;
|
||||||
|
node = DS.GetTarget( aInput, aArc, true );
|
||||||
|
if( node instanceof Components.interfaces.nsIRDFResource ) {
|
||||||
|
return node.Value;
|
||||||
|
}
|
||||||
|
if( node instanceof Components.interfaces.nsIRDFLiteral ) {
|
||||||
|
return node.Value;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function addBookmark(title, uri)
|
||||||
|
{
|
||||||
|
folder = RDF.GetResource("NC:BookmarksRoot");
|
||||||
|
var rSource = BookmarksUtils.createBookmark(title, uri, null, title);
|
||||||
|
var selection = BookmarksUtils.getSelectionFromResource(rSource);
|
||||||
|
var target = BookmarksUtils.getTargetFromFolder(folder);
|
||||||
|
BookmarksUtils.insertAndCheckSelection("newbookmark", selection, target);
|
||||||
|
|
||||||
|
//also update bookmark cache
|
||||||
|
g_bookmarks.unshift([uri, title]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no idea what it does, it Just Works (TM)
|
||||||
|
*
|
||||||
|
* returns number of deleted bookmarks
|
||||||
|
*/
|
||||||
|
function deleteBookmark(url)
|
||||||
|
{
|
||||||
|
var deleted = 0;
|
||||||
|
|
||||||
|
// gNC_NS for trunk, NC_NS for 1.X
|
||||||
|
try {var pNC_NS; pNC_NS = gNC_NS;} catch (err) { pNC_NS = NC_NS;}
|
||||||
|
if(! BMSVC || ! BMDS || ! RDF || ! pNC_NS ) return null;
|
||||||
|
if ( !url) return null; // just in case
|
||||||
|
|
||||||
|
var curfolder = RDF.GetResource("NC:BookmarksRoot");
|
||||||
|
var urlArc = RDF.GetResource(pNC_NS+"URL");
|
||||||
|
var urlLiteral = RDF.GetLiteral(url);
|
||||||
|
if (BMDS.hasArcIn(urlLiteral, urlArc)) {
|
||||||
|
var bmResources, bmResource, title, uri, type, ptype;
|
||||||
|
bmResources = BMSVC.GetSources(urlArc, urlLiteral, true);
|
||||||
|
while (bmResources.hasMoreElements()) {
|
||||||
|
bmResource = bmResources.getNext();
|
||||||
|
type = BookmarksUtils.resolveType(bmResource);
|
||||||
|
if (type != "ImmutableBookmark") {
|
||||||
|
ptype = BookmarksUtils.resolveType(BMSVC.getParent(bmResource));
|
||||||
|
// alert(type);
|
||||||
|
// if ( type == "Folder") // store the current folder
|
||||||
|
// curfolder = bmResource;
|
||||||
|
if ( (type == "Bookmark" || type == "IEFavorite") && ptype != "Livemark") {
|
||||||
|
title = BookmarksUtils.getProperty(bmResource, pNC_NS+"Name");
|
||||||
|
uri = BookmarksUtils.getProperty(bmResource, pNC_NS+"URL");
|
||||||
|
|
||||||
|
if (uri == url)
|
||||||
|
{
|
||||||
|
RDFC.Init(BMDS, BMSVC.getParent(bmResource));
|
||||||
|
RDFC.RemoveElement(bmResource, true);
|
||||||
|
deleted++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// also update bookmark cache, if we removed at least one bookmark
|
||||||
|
if(deleted > 0)
|
||||||
|
bookmarks_loaded = false;
|
||||||
|
|
||||||
|
return deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* call the function like this:
|
||||||
|
var res = new Object();
|
||||||
|
parseBookmarkString("-t tag1,tag2 -T title http://www.orf.at", res);
|
||||||
|
res.tags is an array of tags
|
||||||
|
res.title is the title or "" if no one was given
|
||||||
|
res.url is the url as a string
|
||||||
|
|
||||||
|
returns false, if parsing failed
|
||||||
|
*/
|
||||||
|
function parseBookmarkString(str, res)
|
||||||
|
{
|
||||||
|
res.tags = [];
|
||||||
|
res.title = null;
|
||||||
|
res.url = null;
|
||||||
|
|
||||||
|
var re_title = /^\s*((-t|--title)\s+(\w+|\".*\"))(.*)/;
|
||||||
|
var re_tags = /^\s*((-T|--tags)\s+((\w+)(,\w+)*))(.*)/;
|
||||||
|
var re_url = /^\s*(\".+\"|\S+)(.*)/;
|
||||||
|
|
||||||
|
var match_tags = null;
|
||||||
|
var match_title = null;
|
||||||
|
var match_url = null;
|
||||||
|
|
||||||
|
while(!str.match(/^\s*$/))
|
||||||
|
{
|
||||||
|
/* first check for --tags */
|
||||||
|
match_tags = str.match(re_tags);
|
||||||
|
if(match_tags != null)
|
||||||
|
{
|
||||||
|
str = match_tags[match_tags.length-1]; // the last captured parenthesis is the rest of the string
|
||||||
|
tags = match_tags[3].split(",");
|
||||||
|
res.tags = res.tags.concat(tags);
|
||||||
|
}
|
||||||
|
else /* then for --titles */
|
||||||
|
{
|
||||||
|
|
||||||
|
match_title = str.match(re_title);
|
||||||
|
if(match_title != null)
|
||||||
|
{
|
||||||
|
// only one title allowed
|
||||||
|
if (res.title != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
str = match_title[match_title.length-1]; // the last captured parenthesis is the rest of the string
|
||||||
|
title = match_title[3];
|
||||||
|
if(title.charAt(0) == '"')
|
||||||
|
title = title.substring(1,title.length-1);
|
||||||
|
res.title = title;
|
||||||
|
}
|
||||||
|
else /* at last check for an url */
|
||||||
|
{
|
||||||
|
match_url = str.match(re_url);
|
||||||
|
if (match_url != null)
|
||||||
|
{
|
||||||
|
// only one url allowed
|
||||||
|
if (res.url != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
str = match_url[match_url.length-1]; // the last captured parenthesis is the rest of the string
|
||||||
|
url = match_url[1];
|
||||||
|
if(url.charAt(0) == '"')
|
||||||
|
url = url.substring(1,url.length-1);
|
||||||
|
res.url = url;
|
||||||
|
}
|
||||||
|
else return false; // no url, tag or title found but still text left, abort
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
1682
chrome/content/vimperator/commands.js
Normal file
1682
chrome/content/vimperator/commands.js
Normal file
File diff suppressed because it is too large
Load Diff
486
chrome/content/vimperator/completion.js
Normal file
486
chrome/content/vimperator/completion.js
Normal file
@@ -0,0 +1,486 @@
|
|||||||
|
/*
|
||||||
|
* COMPLETION HANDLING
|
||||||
|
*
|
||||||
|
* also responsible for command history, url history and bookmark handling
|
||||||
|
*/
|
||||||
|
|
||||||
|
// array of all our bookmarks
|
||||||
|
var g_bookmarks = [];
|
||||||
|
var bookmarks_loaded = false;
|
||||||
|
|
||||||
|
// array of all our history items
|
||||||
|
var g_history = [];
|
||||||
|
var history_loaded = false;
|
||||||
|
|
||||||
|
// variables for the tab completion and command history:
|
||||||
|
// -1: filled, but no selection made
|
||||||
|
// >= 0: index of current item in the g_completions array
|
||||||
|
const COMPLETION_UNINITIALIZED = -2; // if we need to build the completion array first
|
||||||
|
const COMPLETION_MAXITEMS = 10;
|
||||||
|
const COMPLETION_CONTEXTLINES = 3;
|
||||||
|
const COMMAND_LINE_HISTORY_SIZE = 500;
|
||||||
|
|
||||||
|
// 2 dimensional: 1st element: what to complete
|
||||||
|
// 2nd element: help description
|
||||||
|
var g_completions = new Array();
|
||||||
|
|
||||||
|
var comp_tab_index = COMPLETION_UNINITIALIZED; // the index in the internal g_completions array
|
||||||
|
var comp_tab_list_offset = 0; // how many items is the displayed list shifted from the internal tab index
|
||||||
|
var comp_tab_startstring = "";
|
||||||
|
var comp_history = new Array();
|
||||||
|
var comp_history_index = -1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* uses the entries in g_completions to fill the listbox
|
||||||
|
* starts at index 'startindex', and shows COMPLETION_MAXITEMS
|
||||||
|
* returns the number of items */
|
||||||
|
function completion_fill_list(startindex)/*{{{*/
|
||||||
|
{
|
||||||
|
// remove all old items first
|
||||||
|
var items = completion_list.getElementsByTagName("listitem");
|
||||||
|
while (items.length > 0) { completion_list.removeChild(items[0]);}
|
||||||
|
|
||||||
|
// find start index
|
||||||
|
//var i = index - 3; // 3 lines of context
|
||||||
|
if (startindex + COMPLETION_MAXITEMS > g_completions.length)
|
||||||
|
startindex = g_completions.length - COMPLETION_MAXITEMS;
|
||||||
|
if (startindex < 0)
|
||||||
|
startindex = 0;
|
||||||
|
|
||||||
|
for(i=startindex; i<g_completions.length && i < startindex + COMPLETION_MAXITEMS; i++)
|
||||||
|
{
|
||||||
|
completion_add_to_list(g_completions[i], false);
|
||||||
|
}
|
||||||
|
//completion_list.hidden = true;
|
||||||
|
// completion_list.setAttribute("rows", (i-startindex).toString());
|
||||||
|
// showStatusbarMessage ( (i-startindex).toString(), 1);
|
||||||
|
// if ( i-startindex > 0) // XXX: respect completetopt setting
|
||||||
|
// completion_list.hidden = false;
|
||||||
|
// else
|
||||||
|
// completion_list.hidden = true;
|
||||||
|
// completion_list.setAttribute("rows", (i-startindex).toString());
|
||||||
|
|
||||||
|
return (i-startindex);
|
||||||
|
}/*}}}*/
|
||||||
|
|
||||||
|
function completion_show_list()/*{{{*/
|
||||||
|
{
|
||||||
|
var items = g_completions.length;
|
||||||
|
if (items > COMPLETION_MAXITEMS)
|
||||||
|
items = COMPLETION_MAXITEMS;
|
||||||
|
if (items > 1) // FIXME
|
||||||
|
{
|
||||||
|
//alert(completion_list.getRowCount().toString());
|
||||||
|
completion_list.setAttribute("rows", items.toString());
|
||||||
|
//completion_list.rowCountChanged(0, items);
|
||||||
|
completion_list.hidden = false;
|
||||||
|
//completion_list.selectedIndex = selected_index;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
completion_list.hidden = true;
|
||||||
|
}/*}}}*/
|
||||||
|
|
||||||
|
/* add a single completion item to the list */
|
||||||
|
function completion_add_to_list(completion_item, at_beginning)/*{{{*/
|
||||||
|
{
|
||||||
|
var item = document.createElement("listitem");
|
||||||
|
var cell1 = document.createElement("listcell");
|
||||||
|
var cell2 = document.createElement("listcell");
|
||||||
|
|
||||||
|
cell1.setAttribute("label", completion_item[0]);
|
||||||
|
cell1.setAttribute("width", "200");
|
||||||
|
cell2.setAttribute("label", completion_item[1]);
|
||||||
|
cell2.setAttribute("style", "color:green; font-family: sans");
|
||||||
|
|
||||||
|
item.appendChild(cell1);
|
||||||
|
item.appendChild(cell2);
|
||||||
|
if (at_beginning == true)
|
||||||
|
{
|
||||||
|
var items = completion_list.getElementsByTagName("listitem");
|
||||||
|
if (items.length > 0)
|
||||||
|
completion_list.insertBefore(item, items[0]);
|
||||||
|
else
|
||||||
|
completion_list.appendChild(item);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
completion_list.appendChild(item);
|
||||||
|
}/*}}}*/
|
||||||
|
|
||||||
|
/* select the next index, refill list if necessary
|
||||||
|
*
|
||||||
|
* changes 'comp_tab_index' */
|
||||||
|
function completion_select_next_item()/*{{{*/
|
||||||
|
{
|
||||||
|
comp_tab_index++;
|
||||||
|
if (comp_tab_index >= g_completions.length) /* wrap around */
|
||||||
|
{
|
||||||
|
comp_tab_index = -1;
|
||||||
|
completion_list.selectedIndex = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (comp_tab_index == 0) // at the top of the list
|
||||||
|
{
|
||||||
|
completion_fill_list(0);
|
||||||
|
comp_tab_list_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var listindex = comp_tab_index - comp_tab_list_offset;
|
||||||
|
// only move the list, if there are still items we can move
|
||||||
|
if (listindex >= COMPLETION_MAXITEMS - COMPLETION_CONTEXTLINES &&
|
||||||
|
comp_tab_list_offset < g_completions.length - COMPLETION_MAXITEMS)
|
||||||
|
{
|
||||||
|
// for speed reason: just remove old item, and add new at the end of the list
|
||||||
|
var items = completion_list.getElementsByTagName("listitem");
|
||||||
|
completion_list.removeChild(items[0]);
|
||||||
|
completion_add_to_list(g_completions[comp_tab_index + COMPLETION_CONTEXTLINES], false);
|
||||||
|
comp_tab_list_offset++;
|
||||||
|
}
|
||||||
|
|
||||||
|
listindex = comp_tab_index - comp_tab_list_offset;
|
||||||
|
completion_list.selectedIndex = listindex;
|
||||||
|
|
||||||
|
showStatusbarMessage(" match " + (comp_tab_index+1).toString() + " of " + g_completions.length.toString() + " ", STATUSFIELD_PROGRESS);
|
||||||
|
}/*}}}*/
|
||||||
|
|
||||||
|
/* select the previous index, refill list if necessary
|
||||||
|
*
|
||||||
|
* changes 'comp_tab_index' */
|
||||||
|
function completion_select_previous_item()/*{{{*/
|
||||||
|
{
|
||||||
|
comp_tab_index--;
|
||||||
|
if (comp_tab_index == -1)
|
||||||
|
{
|
||||||
|
completion_list.selectedIndex = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (comp_tab_index < -1) // go to the end of the list
|
||||||
|
{
|
||||||
|
comp_tab_index = g_completions.length -1;
|
||||||
|
completion_fill_list(g_completions.length - COMPLETION_MAXITEMS);
|
||||||
|
comp_tab_list_offset = g_completions.length - COMPLETION_MAXITEMS;//COMPLETION_MAXITEMS - 1;
|
||||||
|
if (comp_tab_list_offset < 0)
|
||||||
|
comp_tab_list_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var listindex = comp_tab_index - comp_tab_list_offset;
|
||||||
|
// only move the list, if there are still items we can move
|
||||||
|
if (listindex < COMPLETION_CONTEXTLINES && comp_tab_list_offset > 0)
|
||||||
|
{
|
||||||
|
// for speed reason: just remove old item, and add new at the end of the list
|
||||||
|
var items = completion_list.getElementsByTagName("listitem");
|
||||||
|
completion_list.removeChild(items[items.length-1]);
|
||||||
|
completion_add_to_list(g_completions[comp_tab_index - COMPLETION_CONTEXTLINES], true);
|
||||||
|
comp_tab_list_offset--;
|
||||||
|
}
|
||||||
|
|
||||||
|
listindex = comp_tab_index - comp_tab_list_offset;
|
||||||
|
completion_list.selectedIndex = listindex;
|
||||||
|
|
||||||
|
showStatusbarMessage("item " + (comp_tab_index+1).toString() + " of " + g_completions.length.toString(), STATUSFIELD_PROGRESS);
|
||||||
|
}/*}}}*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* filter a list of urls
|
||||||
|
*
|
||||||
|
* may consist of searchengines, boorkmarks and history,
|
||||||
|
* depending on the 'complete' option
|
||||||
|
*/
|
||||||
|
function get_url_completions(filter)/*{{{*/
|
||||||
|
{
|
||||||
|
g_completions = [];
|
||||||
|
|
||||||
|
var cpt = get_pref("complete");
|
||||||
|
// join all completion arrays together
|
||||||
|
for (var i = 0; i < cpt.length; i++)
|
||||||
|
{
|
||||||
|
if (cpt[i] == 's')
|
||||||
|
g_completions = g_completions.concat(get_search_completions(filter));
|
||||||
|
else if (cpt[i] == 'b')
|
||||||
|
g_completions = g_completions.concat(get_bookmark_completions(filter));
|
||||||
|
else if (cpt[i] == 'h')
|
||||||
|
g_completions = g_completions.concat(get_history_completions(filter));
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_completions;
|
||||||
|
}/*}}}*/
|
||||||
|
|
||||||
|
/* discard all entries in the 'urls' array, which don't match 'filter */
|
||||||
|
function filter_url_array(urls, filter, use_regex)/*{{{*/
|
||||||
|
{
|
||||||
|
var filtered = [];
|
||||||
|
// completions which don't match the url but just the description
|
||||||
|
// list them add the end of the array
|
||||||
|
var additional_completions = [];
|
||||||
|
|
||||||
|
var reg, reg2;
|
||||||
|
if (use_regex)
|
||||||
|
{
|
||||||
|
reg = new RegExp("^" + filter, "i");
|
||||||
|
reg2 = new RegExp(filter, "i");
|
||||||
|
}
|
||||||
|
|
||||||
|
outer:
|
||||||
|
for (var i = 0; i < urls.length; ++i)
|
||||||
|
{
|
||||||
|
if (filter != null && filter.length > 0)
|
||||||
|
{
|
||||||
|
// first check if the filter matches in the main part of the URL
|
||||||
|
var bm = urls[i][0].replace(/^.*:\/\/(www)?/, "");
|
||||||
|
bm = bm.replace(/\/.*$/, "");
|
||||||
|
var tokens = bm.split(".");
|
||||||
|
for (var k = 0; k < tokens.length-1; k++) // -1 because we don't search the domain (like .com)
|
||||||
|
{
|
||||||
|
if (use_regex)
|
||||||
|
{
|
||||||
|
if(tokens[k].search(reg) != -1)
|
||||||
|
{
|
||||||
|
filtered.push([urls[i][0], urls[i][1] ]);
|
||||||
|
continue outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (tokens[k].indexOf(filter) == 0)
|
||||||
|
{
|
||||||
|
filtered.push([urls[i][0], urls[i][1] ]);
|
||||||
|
continue outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise check if the filter matches in the description of the bookmark
|
||||||
|
if (use_regex)
|
||||||
|
{
|
||||||
|
if(urls[i][0].search(reg2) == -1 && urls[i][1].search(reg2) == -1)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (urls[i][0].indexOf(filter) == -1 && urls[i][1].indexOf(filter) == -1)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
additional_completions.push([urls[i][0], urls[i][1] ]);
|
||||||
|
}
|
||||||
|
return filtered.concat(additional_completions);
|
||||||
|
}/*}}}*/
|
||||||
|
|
||||||
|
function get_search_completions(filter)/*{{{*/
|
||||||
|
{
|
||||||
|
var search_completions = [];
|
||||||
|
|
||||||
|
var reg = new RegExp("^" + filter, "i");
|
||||||
|
for (var i = 0; i < g_searchengines.length; i++)
|
||||||
|
{
|
||||||
|
if (g_searchengines[i][0].search(reg) != -1)
|
||||||
|
search_completions.push([g_searchengines[i][0] + " ", g_searchengines[i][1] ]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return search_completions;
|
||||||
|
}/*}}}*/
|
||||||
|
|
||||||
|
function get_bookmark_completions(filter)/*{{{*/
|
||||||
|
{
|
||||||
|
if (!bookmarks_loaded)
|
||||||
|
{
|
||||||
|
// update our bookmark cache
|
||||||
|
var RDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService( Components.interfaces.nsIRDFService );
|
||||||
|
var root = RDF.GetResource( "NC:BookmarksRoot" );
|
||||||
|
bookmarks = []; // here getAllChildren will store the bookmarks
|
||||||
|
g_bookmarks = []; // also clear our bookmark cache
|
||||||
|
BookmarksUtils.getAllChildren(root, bookmarks);
|
||||||
|
for(var i = 0; i < bookmarks.length; i++)
|
||||||
|
{
|
||||||
|
if (bookmarks[i][0] && bookmarks[i][1])
|
||||||
|
g_bookmarks.push([bookmarks[i][1].Value, bookmarks[i][0].Value ]);
|
||||||
|
}
|
||||||
|
bookmarks_loaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return filter_url_array(g_bookmarks, filter, true);
|
||||||
|
}/*}}}*/
|
||||||
|
|
||||||
|
function get_history_completions(filter)/*{{{*/
|
||||||
|
{
|
||||||
|
var history = document.getElementById("hiddenHistoryTree");
|
||||||
|
|
||||||
|
// build our history cache
|
||||||
|
if (history_loaded == false)
|
||||||
|
{
|
||||||
|
if (history.hidden)
|
||||||
|
{
|
||||||
|
history.hidden = false;
|
||||||
|
var globalHistory = Components.classes["@mozilla.org/browser/global-history;2"].getService(Components.interfaces.nsIRDFDataSource);
|
||||||
|
history.database.AddDataSource(globalHistory);
|
||||||
|
history_completions = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!history.ref)
|
||||||
|
history.ref = "NC:HistoryRoot";
|
||||||
|
|
||||||
|
const NC_NS = "http://home.netscape.com/NC-rdf#";
|
||||||
|
if (!gRDF)
|
||||||
|
gRDF = Components.classes["@mozilla.org/rdf/rdf-service;1"]
|
||||||
|
.getService(Components.interfaces.nsIRDFService);
|
||||||
|
|
||||||
|
var nameResource = gRDF.GetResource(NC_NS + "Name");
|
||||||
|
var builder = history.builder.QueryInterface(Components.interfaces.nsIXULTreeBuilder);
|
||||||
|
|
||||||
|
var count = history.view.rowCount;
|
||||||
|
for (var i = count-1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
var res = builder.getResourceAtIndex(i);
|
||||||
|
var url = res.Value;
|
||||||
|
// var col = history.columns["Name"];
|
||||||
|
//var title = history.view.getCellText(i, col);
|
||||||
|
var title;
|
||||||
|
var titleRes = history.database.GetTarget(res, nameResource, true);
|
||||||
|
if (!titleRes)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var titleLiteral = titleRes.QueryInterface(Components.interfaces.nsIRDFLiteral);
|
||||||
|
if(titleLiteral)
|
||||||
|
title = titleLiteral.Value;
|
||||||
|
else
|
||||||
|
title = "";
|
||||||
|
|
||||||
|
g_history.push([url, title]);
|
||||||
|
}
|
||||||
|
// if(url.toLowerCase().indexOf(filter.toLowerCase()) > -1)
|
||||||
|
history_loaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return filter_url_array(g_history, filter, true);
|
||||||
|
}/*}}}*/
|
||||||
|
|
||||||
|
function get_command_completions(filter)/*{{{*/
|
||||||
|
{
|
||||||
|
g_completions = [];
|
||||||
|
for(var i=0; i<g_commands.length; i++)
|
||||||
|
{
|
||||||
|
for(var j=0; j<g_commands[i][0].length; j++)
|
||||||
|
{
|
||||||
|
//var re = new RegExp("^" + filter);
|
||||||
|
if (g_commands[i][0][j].indexOf(filter) == 0)
|
||||||
|
{
|
||||||
|
g_completions.push([g_commands[i][0][j], g_commands[i][1]]);
|
||||||
|
break; // only add a command once
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// commands should be sorted anyway, but it doesn't really hurt -> it DOES hurt :(
|
||||||
|
//g_completions.sort();
|
||||||
|
}/*}}}*/
|
||||||
|
|
||||||
|
function get_settings_completions(filter)/*{{{*/
|
||||||
|
{
|
||||||
|
settings_completions = [];
|
||||||
|
var no_mode = false;
|
||||||
|
|
||||||
|
if (filter.indexOf("no") == 0) // boolean option
|
||||||
|
{
|
||||||
|
no_mode = true;
|
||||||
|
filter = filter.substr(2);
|
||||||
|
}
|
||||||
|
// check if filter ends with =, then complete current value
|
||||||
|
else if(filter.length > 0 && filter.lastIndexOf("=") == filter.length -1)
|
||||||
|
{
|
||||||
|
filter = filter.substr(0, filter.length-1);
|
||||||
|
for(var i=0; i<g_settings.length; i++)
|
||||||
|
{
|
||||||
|
for(var j=0; j<g_settings[i][0].length; j++)
|
||||||
|
{
|
||||||
|
if (g_settings[i][0][j] == filter)
|
||||||
|
{
|
||||||
|
settings_completions.push([filter + "=" + g_settings[i][4].call(this), ""]);
|
||||||
|
return settings_completions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return settings_completions;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var i=0; i<g_settings.length; i++)
|
||||||
|
{
|
||||||
|
if (filter == "" || g_settings[i][0][0].indexOf(filter) > -1)
|
||||||
|
{
|
||||||
|
// for 'no'-mode only return bool options
|
||||||
|
if (no_mode)
|
||||||
|
{
|
||||||
|
if (g_settings[i][5] == "bool")
|
||||||
|
settings_completions.push(["no" + g_settings[i][0][0], g_settings[i][1]]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
settings_completions.push([g_settings[i][0][0], g_settings[i][1]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return settings_completions;
|
||||||
|
}/*}}}*/
|
||||||
|
|
||||||
|
////////// COMMAND HISTORY HANDLING ////////////
|
||||||
|
|
||||||
|
function add_to_command_history(str)
|
||||||
|
{
|
||||||
|
/* add string to the command line history */
|
||||||
|
if (str.length >= 2 && comp_history.push(str) > COMMAND_LINE_HISTORY_SIZE)
|
||||||
|
comp_history.shift();
|
||||||
|
}
|
||||||
|
|
||||||
|
function save_history()
|
||||||
|
{
|
||||||
|
set_pref("comp_history", comp_history.join("\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
function load_history()
|
||||||
|
{
|
||||||
|
var hist = get_pref("comp_history", "");
|
||||||
|
comp_history = hist.split("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////// PREVIEW WINDOW //////////////////////
|
||||||
|
|
||||||
|
/* uses the entries in completions to fill the listbox */
|
||||||
|
function preview_window_fill(completions)
|
||||||
|
{
|
||||||
|
// remove all old items first
|
||||||
|
var items = preview_window.getElementsByTagName("listitem");
|
||||||
|
while (items.length > 0) { preview_window.removeChild(items[0]);}
|
||||||
|
|
||||||
|
for(i=0; i<completions.length; i++)
|
||||||
|
{
|
||||||
|
var item = document.createElement("listitem");
|
||||||
|
var cell1 = document.createElement("listcell");
|
||||||
|
var cell2 = document.createElement("listcell");
|
||||||
|
|
||||||
|
cell1.setAttribute("label", completions[i][0]);
|
||||||
|
cell2.setAttribute("label", completions[i][1]);
|
||||||
|
//cell2.setAttribute("style", "color:green; font-family: sans; text-align:right");
|
||||||
|
cell2.setAttribute("style", "color:green; font-family: sans;");
|
||||||
|
|
||||||
|
item.appendChild(cell1);
|
||||||
|
item.appendChild(cell2);
|
||||||
|
preview_window.appendChild(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function preview_window_select(event)
|
||||||
|
{
|
||||||
|
var listcell = document.getElementsByTagName("listcell");
|
||||||
|
// 2 columns for now, use the first column
|
||||||
|
var index = (preview_window.selectedIndex * 2) + 0;
|
||||||
|
var val = listcell[index].getAttribute("label");
|
||||||
|
if (val && event.button == 0 && event.type == "dblclick") // left double click
|
||||||
|
openURLs(val);
|
||||||
|
else if (val && event.button == 1) // middle click
|
||||||
|
openURLsInNewTab(val);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// vim: set fdm=marker :
|
||||||
24
chrome/content/vimperator/contents.rdf
Normal file
24
chrome/content/vimperator/contents.rdf
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
|
||||||
|
|
||||||
|
<RDF:Seq RDF:about="urn:mozilla:package:root">
|
||||||
|
<RDF:li RDF:resource="urn:mozilla:package:vimperator"/>
|
||||||
|
</RDF:Seq>
|
||||||
|
|
||||||
|
<!--<RDF:Seq RDF:about="urn:mozilla:overlays">-->
|
||||||
|
<!--<RDF:li RDF:resource="chrome://browser/content/browser.xul"/>-->
|
||||||
|
<!--</RDF:Seq>-->
|
||||||
|
|
||||||
|
<RDF:Seq RDF:about="chrome://browser/content/browser.xul">
|
||||||
|
<RDF:li>chrome://vimperator/content/vimperator.xul</RDF:li>
|
||||||
|
</RDF:Seq>
|
||||||
|
|
||||||
|
<RDF:Description RDF:about="urn:mozilla:package:vimperator"
|
||||||
|
chrome:displayName="Vimperator"
|
||||||
|
chrome:author="Martin Stubenschrott"
|
||||||
|
chrome:name="vimperator"
|
||||||
|
chrome:extension="true"
|
||||||
|
chrome:description="Make Firefox like Vim">
|
||||||
|
</RDF:Description>
|
||||||
|
</RDF:RDF>
|
||||||
640
chrome/content/vimperator/hints.js
Normal file
640
chrome/content/vimperator/hints.js
Normal file
@@ -0,0 +1,640 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Mozilla Public License Notice
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License
|
||||||
|
* Version 1.1 (the "License"); you may not use this file except in
|
||||||
|
* compliance with the License. You may obtain a copy of the License
|
||||||
|
* at http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS"
|
||||||
|
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||||
|
* the License for the specific language governing rights and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* The Original Code and Idea is the Hit-a-Hint Mozilla extension.
|
||||||
|
* The Initial Developer of the Original Code and the Idea is Pekka
|
||||||
|
* P. Sillanpaa. Portions created by Initial Developer are Copyright
|
||||||
|
* (C) 2004. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Pekka Sillanpaa, Paul Stone
|
||||||
|
* adapted for vimperator use by: Martin Stubenschrott
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const HINT_MODE_QUICK = 0;
|
||||||
|
const HINT_MODE_ALWAYS = 1;
|
||||||
|
const HINT_MODE_EXTENDED = 2;
|
||||||
|
|
||||||
|
function hit_a_hint()
|
||||||
|
{
|
||||||
|
const HINT_PREFIX = 'hah_hint_'; // prefix for the hint id
|
||||||
|
|
||||||
|
// public accessors
|
||||||
|
this.hintsVisible = function() { return isHahModeEnabled; };
|
||||||
|
this.hintedElements = function() { return hintedElems; };
|
||||||
|
this.currentState = function() { return state;};
|
||||||
|
this.setCurrentState = function(s) { state = s;};
|
||||||
|
this.currentMode = function() { return hintmode;};
|
||||||
|
|
||||||
|
var isHahModeEnabled = false; // is typing mode on
|
||||||
|
var hintmode = HINT_MODE_QUICK;
|
||||||
|
var hintedElems = [];
|
||||||
|
var linkNumString = ""; // the typed link number is in this string
|
||||||
|
var linkCount = 0;
|
||||||
|
var state = 0; // 0: empty or processing, 1: a full hint was parsed
|
||||||
|
|
||||||
|
var wins; // frame array
|
||||||
|
|
||||||
|
// each hint element is a clone of this element
|
||||||
|
var hintElemSpan;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// configuration and initialization related functions
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// function load()
|
||||||
|
// {
|
||||||
|
// isHahModeEnabled = false;
|
||||||
|
// hintedElem = null;
|
||||||
|
// }
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// hint activating and loading related functions
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
function startCoordLoader(doc)
|
||||||
|
{
|
||||||
|
win = doc.defaultView;
|
||||||
|
if (!win)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (win.winId != null)
|
||||||
|
{
|
||||||
|
window.clearTimeout(win.coordLoaderId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!wins)
|
||||||
|
wins = new Array();
|
||||||
|
|
||||||
|
win.winId = wins.length;
|
||||||
|
wins.push(win);
|
||||||
|
}
|
||||||
|
// logMessage("winId:"+win.winId);
|
||||||
|
win.res = doc.evaluate(get_pref("hinttags"), doc, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
|
||||||
|
win.coordLoaderId = window.setTimeout("hah.loadCoord(" + win.winId + ", 0);", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loadCoord = function(winId, i)
|
||||||
|
{
|
||||||
|
win = wins[winId];
|
||||||
|
var elem = win.res.snapshotItem(i);
|
||||||
|
|
||||||
|
if (elem)
|
||||||
|
genElemCoords(elem);
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if (i < win.res.snapshotLength && !isHahModeEnabled)
|
||||||
|
window.setTimeout("hah.loadCoord(" + winId + ", "+ i +");", 1);
|
||||||
|
else
|
||||||
|
win.coordLoaderId = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
function genElemCoords(elem)
|
||||||
|
{
|
||||||
|
if (typeof(elem.validCoord) != "undefined")
|
||||||
|
{
|
||||||
|
if (elem.validCoord == elem.ownerDocument.validCoords)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elem.offsetParent)
|
||||||
|
{
|
||||||
|
genElemCoords(elem.offsetParent);
|
||||||
|
elem.absoLeft = elem.offsetParent.absoLeft + elem.offsetLeft;
|
||||||
|
elem.absoTop = elem.offsetParent.absoTop + elem.offsetTop;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
elem.absoLeft = elem.offsetLeft - 5;
|
||||||
|
elem.absoTop = elem.offsetTop;
|
||||||
|
}
|
||||||
|
elem.validCoord = elem.ownerDocument.validCoords;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createHints(win)
|
||||||
|
{
|
||||||
|
if (!win)
|
||||||
|
{
|
||||||
|
win = window._content;
|
||||||
|
linkCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var area = new Array(4);
|
||||||
|
area[0] = win.pageXOffset - 5;
|
||||||
|
area[1] = win.pageYOffset - 5;
|
||||||
|
area[2] = area[0] + win.innerWidth;
|
||||||
|
area[3] = area[1] + win.innerHeight;
|
||||||
|
|
||||||
|
var doc = win.document;
|
||||||
|
var res = doc.evaluate(get_pref("hinttags"), doc, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
|
||||||
|
|
||||||
|
var elem, i;
|
||||||
|
|
||||||
|
hintElemSpan = doc.createElement('SPAN');
|
||||||
|
hintElemSpan.style.cssText = get_pref("hintstyle");
|
||||||
|
hintElemSpan.setAttribute('name', 'hah_hint');
|
||||||
|
|
||||||
|
var hintContainer = doc.getElementById('hah_hints');
|
||||||
|
|
||||||
|
if (hintContainer == null)
|
||||||
|
{
|
||||||
|
genHintContainer(doc);
|
||||||
|
hintContainer = doc.getElementById('hah_hints');
|
||||||
|
}
|
||||||
|
hintContainer.valid_hint_count = 0; // none of these hints should be visible initially
|
||||||
|
|
||||||
|
var hints = hintContainer.childNodes;
|
||||||
|
var maxhints = get_pref("maxhints");
|
||||||
|
for (i = 0; i < res.snapshotLength; i++)
|
||||||
|
{
|
||||||
|
// this saves from script timeouts on pages with some thousand links
|
||||||
|
if (linkCount >= maxhints)
|
||||||
|
break;
|
||||||
|
|
||||||
|
elem = res.snapshotItem(i);
|
||||||
|
genElemCoords(elem);
|
||||||
|
|
||||||
|
// for extended hint mode, show all - even currently hidden - hints
|
||||||
|
if (hintmode == HINT_MODE_QUICK && (elem.absoTop < area[1] || elem.absoTop > area[3] ||
|
||||||
|
elem.absoLeft > area[2] || elem.absoLeft < area[0]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// XXX: what does that do
|
||||||
|
// if (elem.offsetWidth == 0 && elem.offsetHeight == 0)
|
||||||
|
// continue;
|
||||||
|
|
||||||
|
var cs = doc.defaultView.getComputedStyle(elem, null);
|
||||||
|
|
||||||
|
if (cs.getPropertyValue("visibility") == "hidden")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (linkCount < hints.length)
|
||||||
|
hintElem = hints[linkCount];
|
||||||
|
else // need to attach this new hintElem to the hint container
|
||||||
|
{
|
||||||
|
hintElem = hintElemSpan.cloneNode(false);
|
||||||
|
hintContainer.appendChild(hintElem);
|
||||||
|
}
|
||||||
|
|
||||||
|
hintElem.style.display = 'none';
|
||||||
|
hintElem.style.top = elem.absoTop + "px";
|
||||||
|
hintElem.style.left = elem.absoLeft + "px";
|
||||||
|
hintElem.refElem = elem;
|
||||||
|
|
||||||
|
hintContainer.valid_hint_count++; // one more visible hint in this frame
|
||||||
|
linkCount++; // and one more total hint
|
||||||
|
}
|
||||||
|
|
||||||
|
doc.coordsInvalidated = false;
|
||||||
|
|
||||||
|
// recursively create hints
|
||||||
|
for (i = 0; i < win.frames.length; i++)
|
||||||
|
createHints(win.frames[i]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function showHints(win, off)
|
||||||
|
{
|
||||||
|
offset = off; // must be global without 'var' for recursion
|
||||||
|
|
||||||
|
if (!win)
|
||||||
|
win = window._content;
|
||||||
|
|
||||||
|
if (linkCount == 0 && hintmode != HINT_MODE_ALWAYS)
|
||||||
|
{
|
||||||
|
beep();
|
||||||
|
linkNumString = '';
|
||||||
|
hintedElems = [];
|
||||||
|
isHahModeEnabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var doc = win.document;
|
||||||
|
var hintElem = null;
|
||||||
|
var hintContainer = doc.getElementById('hah_hints');
|
||||||
|
var hints = hintContainer.childNodes;
|
||||||
|
var i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < hintContainer.valid_hint_count; i++)
|
||||||
|
{
|
||||||
|
hintText = formatHint(offset+i);
|
||||||
|
hintElem = hints[i];
|
||||||
|
hintElem.style.display = 'inline';
|
||||||
|
//hintElem.style.position = 'absolute';
|
||||||
|
hintElem.innerHTML = hintText;
|
||||||
|
hintElem.id = HINT_PREFIX + hintText;
|
||||||
|
}
|
||||||
|
offset += hintContainer.valid_hint_count;
|
||||||
|
|
||||||
|
// recursively show hints
|
||||||
|
for (j = 0; j < win.frames.length; j++)
|
||||||
|
showHints(win.frames[j], offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* removes all visible hints from doc
|
||||||
|
* or from current document, if doc == null
|
||||||
|
*/
|
||||||
|
function removeHints(win)
|
||||||
|
{
|
||||||
|
if (!win)
|
||||||
|
win = window._content;
|
||||||
|
|
||||||
|
var doc = win.document;
|
||||||
|
var res = doc.evaluate("//HINTS/SPAN", doc, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE , null);
|
||||||
|
var elem, i;
|
||||||
|
|
||||||
|
for (i = 0; i < res.snapshotLength; i++)
|
||||||
|
{
|
||||||
|
elem = res.snapshotItem(i);
|
||||||
|
setHintStyle(elem, get_pref("hintstyle"));
|
||||||
|
elem.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < win.frames.length; i++)
|
||||||
|
removeHints(win.frames[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onResize(event)
|
||||||
|
{
|
||||||
|
doc = event.originalTarget;
|
||||||
|
invalidateCoords(doc);
|
||||||
|
startCoordLoader(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
function invalidateCoords(doc)
|
||||||
|
{
|
||||||
|
if (!doc.coordsInvalidated)
|
||||||
|
{
|
||||||
|
// every element has .validCoord
|
||||||
|
// if it is the same as doc:s .validCoords,
|
||||||
|
// the coordinates have not been regenerated, otherwise they
|
||||||
|
// have. This way we can also use recursive generation
|
||||||
|
// so that the coordinates are generated for every
|
||||||
|
// element just once
|
||||||
|
doc.validCoords = !doc.validCoords;
|
||||||
|
// this is because window can be resized many times
|
||||||
|
// and the coords should be invalidated just once.
|
||||||
|
doc.coordsInvalidated = true;
|
||||||
|
// logMessage(doc.validCoords);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getHintById(id, win)
|
||||||
|
{
|
||||||
|
if (!win)
|
||||||
|
win = window._content;
|
||||||
|
|
||||||
|
var doc = win.document;
|
||||||
|
var elem, i;
|
||||||
|
|
||||||
|
//var hintId = parseInt(id, nums.length);
|
||||||
|
//elem = doc.getElementById(prefix + hintId);
|
||||||
|
elem = doc.getElementById(HINT_PREFIX + id);
|
||||||
|
|
||||||
|
if (elem)
|
||||||
|
{
|
||||||
|
return elem;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < win.frames.length; i++)
|
||||||
|
{
|
||||||
|
elem = getHintById(id, win.frames[i]);
|
||||||
|
if (elem)
|
||||||
|
return elem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatHint(hintNum)
|
||||||
|
{
|
||||||
|
var hintCharacters = get_pref("hintchars");
|
||||||
|
var str = hintNum.toString(hintCharacters.length); // turn hintNum into a base(length) number
|
||||||
|
|
||||||
|
// map the number onto the chars in the numbers string
|
||||||
|
var result = '';
|
||||||
|
// make all links the same length
|
||||||
|
var hintLength = 1;
|
||||||
|
var tmp = linkCount;
|
||||||
|
while((tmp /= hintCharacters.length) > 1.0)
|
||||||
|
hintLength++;
|
||||||
|
while(str.length < hintLength)
|
||||||
|
{
|
||||||
|
result += hintCharacters.charAt(0).toUpperCase();
|
||||||
|
hintLength--;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < str.length; i++)
|
||||||
|
result += (hintCharacters.charAt(parseInt(str[i], hintCharacters.length))).toUpperCase();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setHintStyle(hintElem, styleString)
|
||||||
|
{
|
||||||
|
if (hintElem && hintElem.style)
|
||||||
|
{
|
||||||
|
xTemp = hintElem.style.left;
|
||||||
|
yTemp = hintElem.style.top;
|
||||||
|
hintElem.style.cssText = styleString;
|
||||||
|
hintElem.style.left = xTemp;
|
||||||
|
hintElem.style.top = yTemp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeHintFocus(linkNumString, oldLinkNumString)
|
||||||
|
{
|
||||||
|
var styleString = get_pref("hintstyle");
|
||||||
|
var styleStringFocus = get_pref("focusedhintstyle");
|
||||||
|
var hintElem;
|
||||||
|
|
||||||
|
if (oldLinkNumString.length > 0)
|
||||||
|
{
|
||||||
|
hintElem = getHintById(oldLinkNumString);
|
||||||
|
setHintStyle(hintElem, styleString);
|
||||||
|
}
|
||||||
|
if (linkNumString.length > 0)
|
||||||
|
{
|
||||||
|
hintElem = getHintById(linkNumString);
|
||||||
|
setHintStyle(hintElem, styleStringFocus);
|
||||||
|
if(hintElem)
|
||||||
|
setMouseOverElement(hintElem.refElem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
// if (isHahModeEnabled)
|
||||||
|
// return false;
|
||||||
|
|
||||||
|
hintmode = 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)
|
||||||
|
{
|
||||||
|
isHahModeEnabled = false;
|
||||||
|
hintmode = HINT_MODE_QUICK;
|
||||||
|
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, get_pref("hintstyle"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 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, get_pref("hintstyle"));
|
||||||
|
elem = elem.refElem;
|
||||||
|
var elemTagName = elem.tagName;
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
doc = window._content.document;
|
||||||
|
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*/0, 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*/0, 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.yankHints = function()
|
||||||
|
{
|
||||||
|
var loc = "";
|
||||||
|
var elems = hah.hintedElements();
|
||||||
|
var tmp = "";
|
||||||
|
for(i=0; i<elems.length; i++)
|
||||||
|
{
|
||||||
|
tmp = elems[i].refElem.href;
|
||||||
|
if (typeof(tmp) != 'undefined' && tmp.length > 0)
|
||||||
|
loc += tmp + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
copyToClipboard(loc);
|
||||||
|
echo("Yanked " + loc);
|
||||||
|
};
|
||||||
|
|
||||||
|
function setMouseOverElement(elem)
|
||||||
|
{
|
||||||
|
var doc = window.document;
|
||||||
|
|
||||||
|
if (elem.tagName == 'FRAME' || elem.tagName == 'IFRAME')
|
||||||
|
{
|
||||||
|
elem.contentWindow.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//elem.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
var evt = doc.createEvent('MouseEvents');
|
||||||
|
var x = 0;
|
||||||
|
var y = 0;
|
||||||
|
// for imagemap
|
||||||
|
if (elem.tagName == '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 = get_pref("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)
|
||||||
|
{
|
||||||
|
if (doc.getElementsByTagName('HINTS').length > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hints = doc.createElement('HINTS');
|
||||||
|
hints.id = "hah_hints";
|
||||||
|
hints.valid_hint_count = 0; // initially 0 elements are usable as hints
|
||||||
|
doc.body.appendChild(hints);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initDoc(event)
|
||||||
|
{
|
||||||
|
doc = event.originalTarget;
|
||||||
|
genHintContainer(doc);
|
||||||
|
isHahModeEnabled = false;
|
||||||
|
hintedElems = [];
|
||||||
|
|
||||||
|
if (!doc.validCoords)
|
||||||
|
doc.validCoords = true;
|
||||||
|
else
|
||||||
|
doc.validCoords = false;
|
||||||
|
|
||||||
|
// XXX: prepend a ! ?
|
||||||
|
if (doc.coordsInvalidated)
|
||||||
|
doc.coordsInvalidated = true;
|
||||||
|
else
|
||||||
|
doc.coordsInvalidated = false;
|
||||||
|
|
||||||
|
startCoordLoader(doc);
|
||||||
|
|
||||||
|
if (hintmode == HINT_MODE_ALWAYS)
|
||||||
|
{
|
||||||
|
state = 0;
|
||||||
|
linkCount = 0;
|
||||||
|
linkNumString = '';
|
||||||
|
isHahModeEnabled = true;
|
||||||
|
|
||||||
|
createHints();
|
||||||
|
showHints(null, 0);
|
||||||
|
}
|
||||||
|
//window.setTimeout("this.enableHahMode(HINT_MODE_ALWAYS);", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.document.addEventListener("pageshow", initDoc, null);
|
||||||
|
window.addEventListener("resize", onResize, null);
|
||||||
|
logMessage("HAH initialized.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var hah = new hit_a_hint();
|
||||||
358
chrome/content/vimperator/settings.js
Normal file
358
chrome/content/vimperator/settings.js
Normal file
@@ -0,0 +1,358 @@
|
|||||||
|
// settings.js
|
||||||
|
//
|
||||||
|
// handles all persistent storage of information
|
||||||
|
// to and from the firefox registry
|
||||||
|
|
||||||
|
// the global handle to the root of the firefox settings
|
||||||
|
var g_firefox_prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
|
||||||
|
var g_vimperator_prefs = null;
|
||||||
|
|
||||||
|
// non persistent options
|
||||||
|
var opt_usermode = false;
|
||||||
|
var opt_fullscreen = false;
|
||||||
|
|
||||||
|
/* all user-setable vimperator settings
|
||||||
|
* format:
|
||||||
|
* [
|
||||||
|
* 0: [all names of this setting],
|
||||||
|
* 1: description,
|
||||||
|
* 2: help text,
|
||||||
|
* 3: set_function,
|
||||||
|
* 4: get_function,
|
||||||
|
* 5: type,
|
||||||
|
* 6: default,
|
||||||
|
* 7: checkfunc,
|
||||||
|
* 8: completefunc
|
||||||
|
* ]
|
||||||
|
*/
|
||||||
|
var g_settings = [/*{{{*/
|
||||||
|
[
|
||||||
|
["activate"],
|
||||||
|
"Define when tabs are automatically activated",
|
||||||
|
"Not implemented yet",
|
||||||
|
function(value) { set_pref("activate", value); },
|
||||||
|
function() { return get_pref("activate"); },
|
||||||
|
"stringlist",
|
||||||
|
"quickmark,tabopen,paste",
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
["beep"],
|
||||||
|
"Emit a pc speaker beep on certain errors",
|
||||||
|
null,
|
||||||
|
function(value) { set_pref("beep", value); },
|
||||||
|
function() { return get_pref("beep"); },
|
||||||
|
"boolean",
|
||||||
|
true,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
["complete", "cpt"],
|
||||||
|
"Order and items which are completed at the :[tab]open prompt",
|
||||||
|
"Available items:<br>"+
|
||||||
|
"<ul><li><b>s</b>: Search machines</li><li>"+
|
||||||
|
" <b>b</b>: Bookmarks</li><li>"+
|
||||||
|
" <b>h</b>: History</li></ul>"+
|
||||||
|
"The order is important, so <code class=command>:set complete=bs</code> would list bookmarks first, and then any available quick searches.",
|
||||||
|
function(value) { set_pref("complete", value); },
|
||||||
|
function() { return get_pref("complete"); },
|
||||||
|
"charlist",
|
||||||
|
"sbh",
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
["completeopt", "cot"],
|
||||||
|
"Define how command line completion works",
|
||||||
|
"Not implemented yet.",
|
||||||
|
function(value) { set_pref("completeopt", value); },
|
||||||
|
function() { return get_pref("completeopt"); },
|
||||||
|
"stringlist",
|
||||||
|
"menu",
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
["extendedhinttags", "eht"],
|
||||||
|
"XPath string of hintable elements activated by ';'",
|
||||||
|
null,
|
||||||
|
function(value) { set_pref("extendedhinttags", value); },
|
||||||
|
function() { return get_pref("extendedhinttags"); },
|
||||||
|
"string",
|
||||||
|
"//*[@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @class='lk' or @class='s'] | //input[@type!='hidden'] | //a | //area | //iframe | //textarea | //button | //select",
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
["focusedhintstyle", "fhs"],
|
||||||
|
"CSS specification of focused hints appearance",
|
||||||
|
null,
|
||||||
|
function(value) { set_pref("focusedhintstyle", value); },
|
||||||
|
function() { return get_pref("focusedhintstyle"); },
|
||||||
|
"string",
|
||||||
|
"z-index:500;font:normal normal normal x-small monospace;color:ButtonText;background-color:ButtonShadow;border-color:ButtonShadow;border-width:1px;border-style:solid;padding:0px 1px 0px 1px;position:absolute;",
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
["fullscreen", "fs"],
|
||||||
|
"Shows the current window fullscreen",
|
||||||
|
null,
|
||||||
|
function(value) { opt_fullscreen = value; BrowserFullScreen(); },
|
||||||
|
function() { return opt_fullscreen; },
|
||||||
|
"boolean",
|
||||||
|
false,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
["guioptions", "go"],
|
||||||
|
"Shows or hides the menu, toolbar and scrollbars",
|
||||||
|
"Supported characters:<br><ul><li><b>m</b>: menubar</li><li><b>T</b>: toolbar</ul>",
|
||||||
|
function(value) { set_pref("guioptions", value); set_guioptions(value); },
|
||||||
|
function() { return get_pref("guioptions"); },
|
||||||
|
"charlist",
|
||||||
|
"",
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
["hintchars", "hc"],
|
||||||
|
"String of single characters which can be used to follow hints",
|
||||||
|
null,
|
||||||
|
function(value) { set_pref("hintchars", value); },
|
||||||
|
function() { return get_pref("hintchars"); },
|
||||||
|
"charlist",
|
||||||
|
"hjklasdfgyuiopqwertnmzxcvb",
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
["hintstyle", "hs"],
|
||||||
|
"CSS specification of unfocused hints appearance",
|
||||||
|
null,
|
||||||
|
function(value) { set_pref("hintstyle", value); },
|
||||||
|
function() { return get_pref("hintstyle"); },
|
||||||
|
"string",
|
||||||
|
"z-index:500;font:normal normal normal x-small monospace;color:black;background-color:yellow;border-color:ButtonShadow;border-width:0px;border-style:solid;padding:0px 0px 0px 0px;position:absolute;",
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
["hinttags"],
|
||||||
|
"XPath string of hintable elements activated by 'f'",
|
||||||
|
null,
|
||||||
|
function(value) { set_pref("hinttags", value); },
|
||||||
|
function() { return get_pref("hinttags"); },
|
||||||
|
"string",
|
||||||
|
"//*[@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @class='lk' or @class='s'] | //input[@type!='hidden'] | //a | //area | //iframe | //textarea | //button | //select",
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
["maxhints", "mh"],
|
||||||
|
"Maximum of simultanously shown hints",
|
||||||
|
"If you want to speed up display of hints, choose a smaller value",
|
||||||
|
function(value) { set_pref("maxhints", value); },
|
||||||
|
function() { return get_pref("maxhints"); },
|
||||||
|
"number",
|
||||||
|
250,
|
||||||
|
function (value) { if (value>=1 && value <=1000) return true; else return false; },
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
["preload"],
|
||||||
|
"Speed up first time history/bookmark completion",
|
||||||
|
"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).",
|
||||||
|
function(value) { set_pref("preload", value); },
|
||||||
|
function() { return get_pref("preload"); },
|
||||||
|
"boolean",
|
||||||
|
true,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
["showtabline", "stal"],
|
||||||
|
"Control when to show the tab bar of opened web pages",
|
||||||
|
"Available items:<br>"+
|
||||||
|
"<ul><li><b>0</b>: Never show tab bar</li><li>"+
|
||||||
|
" <b>1</b>: Show tab bar only if more than one tab is open</li><li>"+
|
||||||
|
" <b>2</b>: Always show tab bar</li></ul>"+
|
||||||
|
"Not implemented yet.",
|
||||||
|
function(value) { set_pref("showtabline", value); set_showtabline(value); },
|
||||||
|
function() { return get_pref("showtabline"); },
|
||||||
|
"number",
|
||||||
|
2,
|
||||||
|
function (value) { if (value>=0 && value <=2) return true; else return false; },
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
["usermode", "um"],
|
||||||
|
"Show current website with a minimal stylesheet to make it easily accessible",
|
||||||
|
"Note that this is a local setting for now, later it may be split into a global and <code style=command>:setlocal</code> part",
|
||||||
|
function(value) { opt_usermode = value; setStyleDisabled(value); },
|
||||||
|
function() { return opt_usermode; },
|
||||||
|
"boolean",
|
||||||
|
false,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
]
|
||||||
|
]/*}}}*/
|
||||||
|
|
||||||
|
// return null, if the cmd cannot be found in our g_settings array, or
|
||||||
|
// otherwise a refernce to our command
|
||||||
|
function get_setting(cmd)
|
||||||
|
{
|
||||||
|
for (var i=0; i < g_settings.length; i++)
|
||||||
|
{
|
||||||
|
for (var j=0; j < g_settings[i][0].length; j++)
|
||||||
|
{
|
||||||
|
if (g_settings[i][0][j] == cmd)
|
||||||
|
{
|
||||||
|
return g_settings[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// preference getter functions ///////////// {{{1
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
function get_pref(name, forced_default)
|
||||||
|
{
|
||||||
|
var pref = null;
|
||||||
|
var default_value = "";
|
||||||
|
|
||||||
|
// sometimes this var is not yet inititialized, make sure, it is
|
||||||
|
if (!g_vimperator_prefs)
|
||||||
|
g_vimperator_prefs = g_firefox_prefs.getBranch("extensions.vimperator.");
|
||||||
|
|
||||||
|
if (forced_default) // this argument sets defaults for non-user settable options (like comp_history)
|
||||||
|
default_value = forced_default;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (var i=0; i<g_settings.length; i++)
|
||||||
|
{
|
||||||
|
if (g_settings[i][0][0] == name) // only first name is searched
|
||||||
|
{
|
||||||
|
default_value = g_settings[i][6];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (typeof(default_value) == "string")
|
||||||
|
pref = g_vimperator_prefs.getCharPref(name);
|
||||||
|
else if (typeof(default_value) == "number")
|
||||||
|
pref = g_vimperator_prefs.getIntPref(name);
|
||||||
|
else if (typeof(default_value) == "boolean")
|
||||||
|
pref = g_vimperator_prefs.getBoolPref(name);
|
||||||
|
else
|
||||||
|
pref = default_value;
|
||||||
|
} catch (e)
|
||||||
|
{
|
||||||
|
//alert("error: " + e);
|
||||||
|
pref = default_value;
|
||||||
|
}
|
||||||
|
return pref;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function get_firefox_pref(name, default_value)
|
||||||
|
{
|
||||||
|
var pref;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (typeof(default_value) == "string")
|
||||||
|
pref = g_firefox_prefs.getCharPref(name);
|
||||||
|
else if (typeof(default_value) == "number")
|
||||||
|
pref = g_firefox_prefs.getIntPref(name);
|
||||||
|
else if (typeof(default_value) == "boolean")
|
||||||
|
pref = g_firefox_prefs.getBoolPref(name);
|
||||||
|
else
|
||||||
|
pref = default_value;
|
||||||
|
} catch (e)
|
||||||
|
{
|
||||||
|
pref = default_value;
|
||||||
|
}
|
||||||
|
return pref;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// preference setter functions ///////////// {{{1
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
function set_pref(name, value)
|
||||||
|
{
|
||||||
|
// sometimes this var is not yet inititialized, make sure, it is
|
||||||
|
if (!g_vimperator_prefs)
|
||||||
|
g_vimperator_prefs = g_firefox_prefs.getBranch("extensions.vimperator.");
|
||||||
|
|
||||||
|
if (typeof(value) == "string")
|
||||||
|
g_vimperator_prefs.setCharPref(name, value);
|
||||||
|
else if (typeof(value) == "number")
|
||||||
|
g_vimperator_prefs.setIntPref(name, value);
|
||||||
|
else if (typeof(value) == "boolean")
|
||||||
|
g_vimperator_prefs.setBoolPref(name, value);
|
||||||
|
else
|
||||||
|
echoerr("Unkown typeof pref: " + value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_firefox_pref(name, value)
|
||||||
|
{
|
||||||
|
// NOTE: firefox prefs are always inititialized, no need to re-init
|
||||||
|
|
||||||
|
if (typeof(value) == "string")
|
||||||
|
g_firefox_prefs.setCharPref(name, value);
|
||||||
|
else if (typeof(value) == "number")
|
||||||
|
g_firefox_prefs.setIntPref(name, value);
|
||||||
|
else if (typeof(value) == "boolean")
|
||||||
|
g_firefox_prefs.setBoolPref(name, value);
|
||||||
|
else
|
||||||
|
echoerr("Unkown typeof pref: " + value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// helper functions //////////////////////// {{{1
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
|
||||||
|
function set_guioptions(value)
|
||||||
|
{
|
||||||
|
// hide menubar
|
||||||
|
document.getElementById("toolbar-menubar").collapsed = value.indexOf("m") > -1 ? false : true;
|
||||||
|
document.getElementById("toolbar-menubar").hidden = value.indexOf("m") > -1 ? false : true;
|
||||||
|
// and main toolbar
|
||||||
|
document.getElementById("nav-bar").collapsed = value.indexOf("T") > -1 ? false : true;
|
||||||
|
document.getElementById("nav-bar").hidden = value.indexOf("T") > -1 ? false : true;
|
||||||
|
// and bookmarks toolbar
|
||||||
|
document.getElementById("PersonalToolbar").collapsed = value.indexOf("b") > -1 ? false : true;
|
||||||
|
document.getElementById("PersonalToolbar").hidden = value.indexOf("b") > -1 ? false : true;
|
||||||
|
// and original status bar (default), but show it, e.g. when needed for extensions
|
||||||
|
document.getElementById("status-bar").collapsed = value.indexOf("S") > -1 ? false : true;
|
||||||
|
document.getElementById("status-bar").hidden = value.indexOf("S") > -1 ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_showtabline(value)
|
||||||
|
{
|
||||||
|
// hide tabbar
|
||||||
|
if(value == 0)
|
||||||
|
{
|
||||||
|
gBrowser.mStrip.collapsed = true;
|
||||||
|
gBrowser.mStrip.hidden = true;
|
||||||
|
}
|
||||||
|
else if(value == 1)
|
||||||
|
echo("show tabline only with > 1 page open not impl. yet");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gBrowser.mStrip.collapsed = false;
|
||||||
|
gBrowser.mStrip.hidden = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim: set fdm=marker :
|
||||||
110
chrome/content/vimperator/tags
Normal file
110
chrome/content/vimperator/tags
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
|
||||||
|
!_TAG_FILE_SORTED 2 /0=unsorted, 1=sorted, 2=foldcase/
|
||||||
|
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
|
||||||
|
!_TAG_PROGRAM_NAME Exuberant Ctags //
|
||||||
|
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
|
||||||
|
!_TAG_PROGRAM_VERSION 5.6 //
|
||||||
|
addBookmark bookmarks.js /^function addBookmark(title, uri)$/;" f
|
||||||
|
add_to_command_history completion.js /^function add_to_command_history(str)$/;" f
|
||||||
|
beep commands.js /^function beep()$/;" f
|
||||||
|
bmadd commands.js /^function bmadd(str)$/;" f
|
||||||
|
bmdel commands.js /^function bmdel(str)$/;" f
|
||||||
|
bmshow commands.js /^function bmshow(filter, fullmode)$/;" f
|
||||||
|
changeHintFocus hints.js /^ function changeHintFocus(linkNumString, oldLinkNumString)$/;" f
|
||||||
|
completion_add_to_list completion.js /^function completion_add_to_list(completion_item, at_beginning)\/*{{{*\/$/;" f
|
||||||
|
completion_fill_list completion.js /^function completion_fill_list(startindex)\/*{{{*\/$/;" f
|
||||||
|
completion_select_next_item completion.js /^function completion_select_next_item()\/*{{{*\/$/;" f
|
||||||
|
completion_select_previous_item completion.js /^function completion_select_previous_item()\/*{{{*\/$/;" f
|
||||||
|
completion_show_list completion.js /^function completion_show_list()\/*{{{*\/$/;" f
|
||||||
|
copyToClipboard commands.js /^function copyToClipboard(str)$/;" f
|
||||||
|
createCursorPositionString vimperator.js /^function createCursorPositionString()$/;" f
|
||||||
|
createHints hints.js /^ function createHints(win)$/;" f
|
||||||
|
createProgressBar vimperator.js /^function createProgressBar(aProgress)$/;" f
|
||||||
|
deleteBookmark bookmarks.js /^function deleteBookmark(url)$/;" f
|
||||||
|
del_url_mark commands.js /^function del_url_mark(mark)$/;" f
|
||||||
|
echo commands.js /^function echo(msg)$/;" f
|
||||||
|
echoerr commands.js /^function echoerr(msg)$/;" f
|
||||||
|
execute_command commands.js /^function execute_command(count, cmd, special, args) \/\/ {{{$/;" f
|
||||||
|
filter_url_array completion.js /^function filter_url_array(urls, filter, use_regex)\/*{{{*\/$/;" f
|
||||||
|
focusContent vimperator.js /^function focusContent(clear_command_line, clear_statusline)$/;" f
|
||||||
|
focusNextFrame commands.js /^function focusNextFrame()$/;" f
|
||||||
|
formatHint hints.js /^ function formatHint(hintNum)$/;" f
|
||||||
|
genElemCoords hints.js /^ function genElemCoords(elem)$/;" f
|
||||||
|
genHintContainer hints.js /^ function genHintContainer(doc)$/;" f
|
||||||
|
getCurrentLinkLocation commands.js /^function getCurrentLinkLocation()$/;" f
|
||||||
|
getCurrentLocation commands.js /^function getCurrentLocation()$/;" f
|
||||||
|
getHintById hints.js /^ function getHintById(id, win)$/;" f
|
||||||
|
getLinkNodes vimperator.js /^function getLinkNodes(doc)$/;" f
|
||||||
|
getPageLinkNodes vimperator.js /^function getPageLinkNodes()$/;" f
|
||||||
|
getProperty bookmarks.js /^function getProperty( aInput, aArc, DS )$/;" f
|
||||||
|
get_bookmark_completions completion.js /^function get_bookmark_completions(filter)\/*{{{*\/$/;" f
|
||||||
|
get_command commands.js /^function get_command(cmd) \/\/ {{{$/;" f
|
||||||
|
get_command_completions completion.js /^function get_command_completions(filter)\/*{{{*\/$/;" f
|
||||||
|
get_firefox_pref settings.js /^function get_firefox_pref(name, default_value)$/;" f
|
||||||
|
get_history_completions completion.js /^function get_history_completions(filter)\/*{{{*\/$/;" f
|
||||||
|
get_pref settings.js /^function get_pref(name, forced_default)$/;" f
|
||||||
|
get_search_completions completion.js /^function get_search_completions(filter)\/*{{{*\/$/;" f
|
||||||
|
get_setting settings.js /^function get_setting(cmd)$/;" f
|
||||||
|
get_settings_completions completion.js /^function get_settings_completions(filter)\/*{{{*\/$/;" f
|
||||||
|
get_url_completions completion.js /^function get_url_completions(filter)\/*{{{*\/$/;" f
|
||||||
|
get_url_mark commands.js /^function get_url_mark(mark)$/;" f
|
||||||
|
goUp commands.js /^function goUp() \/\/ FIXME$/;" f
|
||||||
|
help commands.js /^function help(section)$/;" f
|
||||||
|
hit_a_hint hints.js /^function hit_a_hint()$/;" f
|
||||||
|
hsshow commands.js /^function hsshow(filter, fullmode)$/;" f
|
||||||
|
init vimperator.js /^function init()$/;" f
|
||||||
|
initDoc hints.js /^ function initDoc(event)$/;" f
|
||||||
|
invalidateCoords hints.js /^ function invalidateCoords(doc)$/;" f
|
||||||
|
isFormElemFocused vimperator.js /^function isFormElemFocused()$/;" f
|
||||||
|
keyToString vimperator.js /^function keyToString(event)$/;" f
|
||||||
|
load_history completion.js /^function load_history()$/;" f
|
||||||
|
logMessage vimperator.js /^function logMessage(msg)$/;" f
|
||||||
|
makeHelpString commands.js /^ function makeHelpString(commands, color, beg, end, func)$/;" f
|
||||||
|
makeSettingsHelpString commands.js /^ function makeSettingsHelpString(command)$/;" f
|
||||||
|
nsBrowserStatusHandler vimperator.js /^function nsBrowserStatusHandler() \/*{{{*\/$/;" f
|
||||||
|
onBlur vimperator.js /^function onBlur() \/\/ FIXME: needed?$/;" f
|
||||||
|
onCommandBarInput vimperator.js /^function onCommandBarInput(event)$/;" f
|
||||||
|
onCommandBarKeypress vimperator.js /^function onCommandBarKeypress(evt)\/*{{{*\/$/;" f
|
||||||
|
onEscape vimperator.js /^function onEscape()$/;" f
|
||||||
|
onResize hints.js /^ function onResize(event)$/;" f
|
||||||
|
onVimperatorKeypress vimperator.js /^function onVimperatorKeypress(event)\/*{{{*\/$/;" f
|
||||||
|
openURLs commands.js /^function openURLs(str)$/;" f
|
||||||
|
openURLsInNewTab commands.js /^function openURLsInNewTab(str, activate)$/;" f
|
||||||
|
openVimperatorBar vimperator.js /^function openVimperatorBar(str)$/;" f
|
||||||
|
outputAddonsList commands.js /^function outputAddonsList(aTarget)$/;" f
|
||||||
|
parseBookmarkString bookmarks.js /^function parseBookmarkString(str, res)$/;" f
|
||||||
|
preview_window_fill completion.js /^function preview_window_fill(completions)$/;" f
|
||||||
|
preview_window_select completion.js /^function preview_window_select(event)$/;" f
|
||||||
|
quit commands.js /^function quit(save_session)$/;" f
|
||||||
|
reload commands.js /^function reload(all_tabs)$/;" f
|
||||||
|
removeHints hints.js /^ function removeHints(win)$/;" f
|
||||||
|
save_history completion.js /^function save_history()$/;" f
|
||||||
|
scrollBufferAbsolute commands.js /^function scrollBufferAbsolute(horizontal, vertical)$/;" f
|
||||||
|
scrollBufferRelative commands.js /^function scrollBufferRelative(right, down)$/;" f
|
||||||
|
selectInput commands.js /^function selectInput()$/;" f
|
||||||
|
set commands.js /^function set(args, special)$/;" f
|
||||||
|
setHintStyle hints.js /^ function setHintStyle(hintElem, styleString)$/;" f
|
||||||
|
setMouseOverElement hints.js /^ function setMouseOverElement(elem)$/;" f
|
||||||
|
setStatusbarColor vimperator.js /^function setStatusbarColor(color)$/;" f
|
||||||
|
set_firefox_pref settings.js /^function set_firefox_pref(name, value)$/;" f
|
||||||
|
set_guioptions settings.js /^function set_guioptions(value)$/;" f
|
||||||
|
set_location_mark commands.js /^function set_location_mark(mark)$/;" f
|
||||||
|
set_pref settings.js /^function set_pref(name, value)$/;" f
|
||||||
|
set_showtabline settings.js /^function set_showtabline(value)$/;" f
|
||||||
|
set_url_mark commands.js /^function set_url_mark(mark, url)$/;" f
|
||||||
|
showHints hints.js /^ function showHints(win, off)$/;" f
|
||||||
|
showStatusbarMessage vimperator.js /^function showStatusbarMessage(msg, field)$/;" f
|
||||||
|
show_location_marks commands.js /^function show_location_marks(mark)$/;" f
|
||||||
|
show_url_marks commands.js /^function show_url_marks(mark)$/;" f
|
||||||
|
source commands.js /^function source(filename)$/;" f
|
||||||
|
startCoordLoader hints.js /^ function startCoordLoader(doc)$/;" f
|
||||||
|
stepInHistory commands.js /^function stepInHistory(steps)$/;" f
|
||||||
|
stringToURLs commands.js /^function stringToURLs(str)$/;" f
|
||||||
|
tab_go commands.js /^function tab_go(index)$/;" f
|
||||||
|
tab_remove commands.js /^function tab_remove(count, focus_left_tab, quit_on_last_tab)$/;" f
|
||||||
|
toggle_images commands.js /^function toggle_images() {$/;" f
|
||||||
|
unload vimperator.js /^function unload()$/;" f
|
||||||
|
updateStatusbar vimperator.js /^function updateStatusbar()$/;" f
|
||||||
|
yankCurrentLocation commands.js /^function yankCurrentLocation()$/;" f
|
||||||
|
zoom_in commands.js /^function zoom_in(factor)$/;" f
|
||||||
|
zoom_to commands.js /^function zoom_to(value)$/;" f
|
||||||
970
chrome/content/vimperator/vimperator.js
Normal file
970
chrome/content/vimperator/vimperator.js
Normal file
@@ -0,0 +1,970 @@
|
|||||||
|
/***** BEGIN LICENSE BLOCK ***** {{{
|
||||||
|
Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
|
||||||
|
The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
http://www.mozilla.org/MPL/
|
||||||
|
|
||||||
|
Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
for the specific language governing rights and limitations under the
|
||||||
|
License.
|
||||||
|
|
||||||
|
(c) 2006-2007: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||||
|
|
||||||
|
Alternatively, the contents of this file may be used under the terms of
|
||||||
|
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
of those above. If you wish to allow use of your version of this file only
|
||||||
|
under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
use your version of this file under the terms of the MPL, indicate your
|
||||||
|
decision by deleting the provisions above and replace them with the notice
|
||||||
|
and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
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.
|
||||||
|
}}} ***** END LICENSE BLOCK *****/
|
||||||
|
|
||||||
|
var Modes = { // XXX: not yet used
|
||||||
|
MODE_NORMAL: 1,
|
||||||
|
MODE_INSERT: 2,
|
||||||
|
MODE_HAH_MAGIC: 3 // when we are holding space for hah input
|
||||||
|
};
|
||||||
|
var current_mode = Modes.MODE_NORMAL;
|
||||||
|
var popup_allowed_events; // need to change and reset this firefox pref
|
||||||
|
|
||||||
|
var g_inputbuffer = ""; // here we store partial commands (e.g. 'g' if you want to type 'gg')
|
||||||
|
var g_count = -1; // the parsed integer of g_inputbuffer, or -1 if no count was given
|
||||||
|
|
||||||
|
// handles to our gui elements
|
||||||
|
var preview_window = null;
|
||||||
|
var status_line = null;
|
||||||
|
var completion_list = null;
|
||||||
|
var command_line = null;
|
||||||
|
|
||||||
|
// our status bar fields
|
||||||
|
const STATUSFIELD_URL = 1;
|
||||||
|
const STATUSFIELD_INPUTBUFFER = 2;
|
||||||
|
const STATUSFIELD_PROGRESS = 3;
|
||||||
|
const STATUSFIELD_BUFFERS = 4;
|
||||||
|
const STATUSFIELD_CURSOR_POSITION = 5;
|
||||||
|
|
||||||
|
|
||||||
|
/* this function reacts to status bar and url changes which are sent from
|
||||||
|
the mozilla core */
|
||||||
|
function nsBrowserStatusHandler() /*{{{*/
|
||||||
|
{
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
nsBrowserStatusHandler.prototype =
|
||||||
|
{
|
||||||
|
QueryInterface : function(aIID)
|
||||||
|
{
|
||||||
|
if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
|
||||||
|
aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
|
||||||
|
aIID.equals(Components.interfaces.nsIXULBrowserWindow) ||
|
||||||
|
aIID.equals(Components.interfaces.nsISupports))
|
||||||
|
return this;
|
||||||
|
throw Components.results.NS_NOINTERFACE;
|
||||||
|
},
|
||||||
|
|
||||||
|
init : function()
|
||||||
|
{
|
||||||
|
},
|
||||||
|
|
||||||
|
setOverLink : function(link, b)
|
||||||
|
{
|
||||||
|
echo(link);
|
||||||
|
},
|
||||||
|
setJSStatus : function(status)
|
||||||
|
{
|
||||||
|
// echo("setJSStatus");
|
||||||
|
// this.updateStatusField(status);
|
||||||
|
},
|
||||||
|
setJSDefaultStatus : function(status)
|
||||||
|
{
|
||||||
|
// echo("setJSDefaultStatus");
|
||||||
|
// this.updateStatusField(status);
|
||||||
|
},
|
||||||
|
setDefaultStatus : function(status)
|
||||||
|
{
|
||||||
|
// echo("setDefaultStatus");
|
||||||
|
// this.updateStatusField(status);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
onStateChange:function(aProgress,aRequest,aFlag,aStatus)
|
||||||
|
{
|
||||||
|
//alert("state change");
|
||||||
|
const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
|
||||||
|
const nsIChannel = Components.interfaces.nsIChannel;
|
||||||
|
if (aFlag & nsIWebProgressListener.STATE_START && aRequest && aRequest.URI)
|
||||||
|
{
|
||||||
|
var toLoadUrl = aRequest.URI.spec;
|
||||||
|
}
|
||||||
|
else if (aFlag & nsIWebProgressListener.STATE_STOP)
|
||||||
|
{
|
||||||
|
updateStatusbar();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
onLocationChange:function (aWebProgress, aRequest, aLocation)
|
||||||
|
{
|
||||||
|
UpdateBackForwardButtons();
|
||||||
|
var url = aLocation.spec;
|
||||||
|
gURLBar.value = url; // also update the original firefox location bar
|
||||||
|
|
||||||
|
// onLocationChange is also called when switching/deleting tabs
|
||||||
|
if (hah.currentMode() != HINT_MODE_ALWAYS)
|
||||||
|
hah.disableHahMode();
|
||||||
|
|
||||||
|
// updating history cache is not done here but in
|
||||||
|
// the 'pageshow' event handler, because at this point I don't
|
||||||
|
// have access to the url title
|
||||||
|
},
|
||||||
|
onProgressChange:function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress)
|
||||||
|
{
|
||||||
|
showStatusbarMessage(createProgressBar(aCurTotalProgress/aMaxTotalProgress), STATUSFIELD_PROGRESS);
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
onStatusChange:function (aWebProgress, aRequest, aStatus, aMessage)
|
||||||
|
{
|
||||||
|
showStatusbarMessage(aMessage, STATUSFIELD_URL);
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
onSecurityChange:function (aWebProgress, aRequest, aState)
|
||||||
|
{
|
||||||
|
const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
|
||||||
|
if(aState & nsIWebProgressListener.STATE_IS_INSECURE)
|
||||||
|
setStatusbarColor("transparent");
|
||||||
|
else if(aState & nsIWebProgressListener.STATE_IS_BROKEN)
|
||||||
|
setStatusbarColor("orange");
|
||||||
|
else if(aState & nsIWebProgressListener.STATE_IS_SECURE)
|
||||||
|
setStatusbarColor("yellow");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//onLinkIconAvailable:function(a){}
|
||||||
|
|
||||||
|
};/*}}}*/
|
||||||
|
|
||||||
|
window.addEventListener("load", init, false);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
// init/uninit //////////////////////////////////////////////////// {{{1
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
function init()
|
||||||
|
{
|
||||||
|
preview_window = document.getElementById("vim-preview_window");
|
||||||
|
status_line = document.getElementById("vim-statusbar");
|
||||||
|
completion_list = document.getElementById("vim-completion");
|
||||||
|
command_line = document.getElementById("vim-commandbar");
|
||||||
|
if (!completion_list || !command_line)
|
||||||
|
alert("GUI not correctly created! Strange things will happen (until I find out, how to exit this script by code)");
|
||||||
|
|
||||||
|
// Setup our status handler - from browser.js
|
||||||
|
window.XULBrowserWindow = new nsBrowserStatusHandler();
|
||||||
|
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||||
|
.getInterface(Components.interfaces.nsIWebNavigation)
|
||||||
|
.QueryInterface(Components.interfaces.nsIDocShellTreeItem).treeOwner
|
||||||
|
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||||
|
.getInterface(Components.interfaces.nsIXULWindow)
|
||||||
|
.XULBrowserWindow = window.XULBrowserWindow;
|
||||||
|
|
||||||
|
|
||||||
|
window.addEventListener("unload", unload, false);
|
||||||
|
window.addEventListener("keypress", onVimperatorKeypress, true);
|
||||||
|
// window.addEventListener("keyup", onVimperatorKeyup, true);
|
||||||
|
// window.addEventListener("keydown", onVimperatorKeydown, true);
|
||||||
|
|
||||||
|
// this handler is for middle click only in the content
|
||||||
|
//window.addEventListener("mousedown", onVimperatorKeypress, true);
|
||||||
|
//content.mPanelContainer.addEventListener("mousedown", onVimperatorKeypress, true);
|
||||||
|
//document.getElementById("content").onclick = function(event) { alert("foo"); };
|
||||||
|
|
||||||
|
// these 4 events require >=firefox-2.0 beta1
|
||||||
|
window.addEventListener("TabMove", updateStatusbar, false);
|
||||||
|
window.addEventListener("TabOpen", updateStatusbar, false);
|
||||||
|
window.addEventListener("TabClose", updateStatusbar, false);
|
||||||
|
//window.addEventListener("TabSelect", updateStatusbar, false);
|
||||||
|
window.addEventListener("TabSelect", function(event)
|
||||||
|
{
|
||||||
|
//alert("select");
|
||||||
|
if (hah.currentMode == HINT_MODE_ALWAYS)
|
||||||
|
{
|
||||||
|
hah.disableHahMode();
|
||||||
|
hah.enableHahMode(HINT_MODE_ALWAYS);
|
||||||
|
}
|
||||||
|
updateStatusbar();
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
/*** load our preferences ***/
|
||||||
|
load_history();
|
||||||
|
|
||||||
|
set_showtabline(get_pref("showtabline"));
|
||||||
|
set_guioptions(get_pref("guioptions"));
|
||||||
|
|
||||||
|
// work around firefox popup blocker
|
||||||
|
popup_allowed_events = get_firefox_pref('dom.popup_allowed_events', 'change click dblclick mouseup reset submit');
|
||||||
|
if (!popup_allowed_events.match("keypress"))
|
||||||
|
set_firefox_pref('dom.popup_allowed_events', popup_allowed_events + " keypress");
|
||||||
|
|
||||||
|
// we have our own typeahead find implementation
|
||||||
|
set_firefox_pref('accessibility.typeaheadfind.autostart', false);
|
||||||
|
set_firefox_pref('accessibility.typeaheadfind', false); // actually the above setting should do it, but has no effect in firefox
|
||||||
|
|
||||||
|
// first time intro message
|
||||||
|
if (get_pref("firsttime", true))
|
||||||
|
{
|
||||||
|
setTimeout(function() {
|
||||||
|
var tab = openURLsInNewTab("about:blank", true);
|
||||||
|
BrowserStop();
|
||||||
|
help();
|
||||||
|
set_pref("firsttime", false);
|
||||||
|
},1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// update our history cache when a new page is shown
|
||||||
|
// XXX: there should be a cleaner way with onload() handler, but it just
|
||||||
|
// does not work out well for me :(
|
||||||
|
window.document.addEventListener("pageshow", function(event)
|
||||||
|
{
|
||||||
|
if (!event.persisted) // only if not bypassing cache
|
||||||
|
{
|
||||||
|
var url = getCurrentLocation();
|
||||||
|
var title = document.title;
|
||||||
|
for(var i=0; i<g_history.length; i++)
|
||||||
|
{
|
||||||
|
if(g_history[i][0] == url)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_history.unshift([url, title]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, null);
|
||||||
|
|
||||||
|
// called when the window is scrolled.
|
||||||
|
window.onscroll = function (event)
|
||||||
|
{
|
||||||
|
showStatusbarMessage(createCursorPositionString(), STATUSFIELD_CURSOR_POSITION);
|
||||||
|
};
|
||||||
|
|
||||||
|
gURLBar.blur();
|
||||||
|
focusContent(true, true);
|
||||||
|
|
||||||
|
// everything important is done, register a preload handler to speed up first time history cache
|
||||||
|
if(get_pref("preload"))
|
||||||
|
setTimeout(function() { get_url_completions(""); } , 100);
|
||||||
|
|
||||||
|
logMessage("Initialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
function unload()
|
||||||
|
{
|
||||||
|
/*** save our preferences ***/
|
||||||
|
save_history();
|
||||||
|
|
||||||
|
// reset firefox pref
|
||||||
|
if (get_firefox_pref('dom.popup_allowed_events',
|
||||||
|
'change click dblclick mouseup reset submit') == popup_allowed_events + " keypress")
|
||||||
|
set_firefox_pref('dom.popup_allowed_events', popup_allowed_events);
|
||||||
|
|
||||||
|
// XXX: not needed anymore?: window.getBrowser().removeProgressListener(urlChangeListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
// keyboard input handling //////////////////////////////////////// {{{1
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
function onVimperatorKeypress(event)/*{{{*/
|
||||||
|
{
|
||||||
|
// XXX: for now only, later: input mappings if form element focused
|
||||||
|
if (isFormElemFocused())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
// // FIXME: handle middle click in content area {{{
|
||||||
|
// // alert(event.target.id);
|
||||||
|
// if (/*event.type == 'mousedown' && */event.button == 1 && event.target.id == 'content')
|
||||||
|
// {
|
||||||
|
// //echo("foo " + event.target.id);
|
||||||
|
// //if (document.commandDispatcher.focusedElement == command_line.inputField)
|
||||||
|
// {
|
||||||
|
// //alert(command_line.value.substring(0, command_line.selectionStart));
|
||||||
|
// command_line.value = command_line.value.substring(0, command_line.selectionStart) +
|
||||||
|
// readFromClipboard() +
|
||||||
|
// command_line.value.substring(command_line.selectionEnd, command_line.value.length);
|
||||||
|
// alert(command_line.value);
|
||||||
|
// }
|
||||||
|
// //else
|
||||||
|
// // {
|
||||||
|
// // openURLs(readFromClipboard());
|
||||||
|
// // }
|
||||||
|
// return true;
|
||||||
|
// } }}}
|
||||||
|
|
||||||
|
// change the event to a usable string representation
|
||||||
|
var key = keyToString(event);
|
||||||
|
if (key == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// if Hit-a-hint mode is on, special handling of keys is required
|
||||||
|
// g_hint_mappings is used
|
||||||
|
if (hah.hintsVisible())
|
||||||
|
{
|
||||||
|
// never propagate this key to firefox, when hints are visible
|
||||||
|
event.preventDefault();
|
||||||
|
event.preventBubble();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
for (i = 0; i < g_hint_mappings.length; i++)
|
||||||
|
{
|
||||||
|
if(g_hint_mappings[i][0] == key)
|
||||||
|
{
|
||||||
|
if(g_hint_mappings[i][3] == true || hah.currentState() == 1)
|
||||||
|
{
|
||||||
|
//g_hint_mappings[i][1].call(this, event);
|
||||||
|
eval(g_hint_mappings[i][1]);
|
||||||
|
if (g_hint_mappings[i][2] == true) // stop processing this event
|
||||||
|
{
|
||||||
|
hah.disableHahMode();
|
||||||
|
g_inputbuffer = "";
|
||||||
|
updateStatusbar();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// make sure that YOU update the statusbar message yourself
|
||||||
|
// first in g_hint_mappings when in this mode!
|
||||||
|
updateStatusbar();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no mapping found, beep()
|
||||||
|
if (hah.currentState() == 1)
|
||||||
|
{
|
||||||
|
beep();
|
||||||
|
hah.disableHahMode();
|
||||||
|
g_inputbuffer = "";
|
||||||
|
updateStatusbar();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we came here, let hit-a-hint process the key as it is part
|
||||||
|
// of a partial link
|
||||||
|
var res = hah.processEvent(event);
|
||||||
|
if (res < 0) // error occured processing this key
|
||||||
|
{
|
||||||
|
beep();
|
||||||
|
if(hah.currentMode() == HINT_MODE_QUICK)
|
||||||
|
hah.disableHahMode();
|
||||||
|
else // ALWAYS mode
|
||||||
|
hah.resetHintedElements();
|
||||||
|
g_inputbuffer = "";
|
||||||
|
}
|
||||||
|
else if (res == 0 || hah.currentMode() == HINT_MODE_EXTENDED) // key processed, part of a larger hint
|
||||||
|
g_inputbuffer += key;
|
||||||
|
else // this key completed a quick hint
|
||||||
|
{
|
||||||
|
// if the hint is all in UPPERCASE, open it in new tab
|
||||||
|
g_inputbuffer += key;
|
||||||
|
if (g_inputbuffer.toUpperCase() == g_inputbuffer)
|
||||||
|
hah.openHints(true, false);
|
||||||
|
else // open in current window
|
||||||
|
hah.openHints(false, false);
|
||||||
|
|
||||||
|
if(hah.currentMode() == HINT_MODE_QUICK)
|
||||||
|
hah.disableHahMode();
|
||||||
|
else // ALWAYS mode
|
||||||
|
hah.resetHintedElements();
|
||||||
|
|
||||||
|
g_inputbuffer = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
updateStatusbar();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set this variable to true, if we have the start of a mapping
|
||||||
|
var couldBecomeCompleteMapping = false;
|
||||||
|
var count_str = g_inputbuffer.match(/^[0-9]*/)[0];
|
||||||
|
|
||||||
|
// counts must be at the start of a complete mapping (10j -> go 10 lines down)
|
||||||
|
if (event.charCode >= 48 && event.charCode <= 57 && !(event.ctrlKey || event.altKey))
|
||||||
|
{
|
||||||
|
if (g_inputbuffer.search(/[^0-9]/) != -1)
|
||||||
|
{
|
||||||
|
g_inputbuffer = "";
|
||||||
|
beep();
|
||||||
|
updateStatusbar();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// handle '0' specially to allow binding of 0
|
||||||
|
if (g_inputbuffer != "" || key != "0")
|
||||||
|
{
|
||||||
|
g_inputbuffer += key;
|
||||||
|
updateStatusbar();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// else let the flow continue, and check if 0 is a mapping
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i in g_mappings)
|
||||||
|
{
|
||||||
|
// each internal mapping can have multiple keys
|
||||||
|
for (var j in g_mappings[i][0])
|
||||||
|
{
|
||||||
|
var mapping = g_mappings[i][0][j];
|
||||||
|
// alert("key: " + key +" - mapping: "+ mapping + " - g_input: " + g_inputbuffer);
|
||||||
|
if(count_str + mapping == g_inputbuffer + key)
|
||||||
|
{
|
||||||
|
g_count = parseInt(count_str, 10);
|
||||||
|
if (isNaN(g_count))
|
||||||
|
g_count = -1;
|
||||||
|
|
||||||
|
// allow null (= no operation) mappings
|
||||||
|
if(g_mappings[i][3] != null)
|
||||||
|
g_mappings[i][3].call(this, g_count);
|
||||||
|
|
||||||
|
// command executed, reset input buffer
|
||||||
|
g_inputbuffer = "";
|
||||||
|
updateStatusbar();
|
||||||
|
event.preventDefault();
|
||||||
|
event.preventBubble();
|
||||||
|
event.stopPropagation();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if ((count_str+mapping).indexOf(g_inputbuffer + key) == 0)
|
||||||
|
{
|
||||||
|
couldBecomeCompleteMapping = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (couldBecomeCompleteMapping)
|
||||||
|
{
|
||||||
|
g_inputbuffer += key;
|
||||||
|
event.preventDefault();
|
||||||
|
event.preventBubble();
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_inputbuffer = "";
|
||||||
|
beep();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateStatusbar();
|
||||||
|
return false;
|
||||||
|
}/*}}}*/
|
||||||
|
function onCommandBarKeypress(evt)/*{{{*/
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
/* parse our command string into tokens */
|
||||||
|
var command = command_line.value;
|
||||||
|
|
||||||
|
var matches1 = command.match(/^:(\d+)/);
|
||||||
|
var matches2 = command.match(/^:(\d+)?([a-zA-Z!]+)/);
|
||||||
|
var matches3 = command.match(/^:(\d+)?([a-zA-Z!]+)\s*(.*?)\s*$/);
|
||||||
|
var count = 0;
|
||||||
|
var cmd = "";
|
||||||
|
var args= "";
|
||||||
|
var special = false;
|
||||||
|
|
||||||
|
if (matches1 != null && matches1.length == 2)
|
||||||
|
count = parseInt(matches1[1], 10);
|
||||||
|
if (matches2 != null && matches2.length >= 3)
|
||||||
|
cmd = matches2[2];
|
||||||
|
if (matches3 != null && matches3.length >= 4)
|
||||||
|
args = matches3[3];
|
||||||
|
|
||||||
|
/* if the user executes a command with ! at the end */
|
||||||
|
if (cmd.length - 1 == cmd.lastIndexOf("!"))
|
||||||
|
{
|
||||||
|
special = true;
|
||||||
|
cmd = cmd.replace(/!$/, "");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
special = false;
|
||||||
|
|
||||||
|
|
||||||
|
/* user pressed ENTER to carry out a command */
|
||||||
|
if (evt.keyCode == KeyEvent.DOM_VK_RETURN)
|
||||||
|
{
|
||||||
|
// unfocus command line first
|
||||||
|
focusContent(false, true); // also sets comp_tab_index to -1
|
||||||
|
add_to_command_history(command);
|
||||||
|
|
||||||
|
execute_command(count, cmd, special, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (evt.keyCode == KeyEvent.DOM_VK_ESCAPE)
|
||||||
|
{
|
||||||
|
add_to_command_history(command);
|
||||||
|
focusContent(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* user pressed UP or DOWN arrow to cycle completion */
|
||||||
|
else if (evt.keyCode == KeyEvent.DOM_VK_UP || evt.keyCode == KeyEvent.DOM_VK_DOWN)
|
||||||
|
{
|
||||||
|
/* save 'start' position for iterating through the history */
|
||||||
|
if (comp_history_index == -1)
|
||||||
|
{
|
||||||
|
comp_history_index = comp_history.length;
|
||||||
|
comp_history_start = command_line.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (comp_history_index >= -1 && comp_history_index <= comp_history.length)
|
||||||
|
{
|
||||||
|
evt.keyCode == KeyEvent.DOM_VK_UP ? comp_history_index-- : comp_history_index++;
|
||||||
|
if (comp_history_index == comp_history.length) // user pressed DOWN when there is no newer history item
|
||||||
|
{
|
||||||
|
command_line.value = comp_history_start;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we are at either end of the list, reset the counter, break the loop and beep */
|
||||||
|
if((evt.keyCode == KeyEvent.DOM_VK_UP && comp_history_index <= -1) ||
|
||||||
|
(evt.keyCode == KeyEvent.DOM_VK_DOWN && comp_history_index >= comp_history.length))
|
||||||
|
{
|
||||||
|
evt.keyCode == KeyEvent.DOM_VK_UP ? comp_history_index++ : comp_history_index--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (comp_history[comp_history_index].indexOf(comp_history_start) == 0)
|
||||||
|
{
|
||||||
|
command_line.value = comp_history[comp_history_index];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
beep();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* user pressed TAB to get completions of a command */
|
||||||
|
else if (evt.keyCode == KeyEvent.DOM_VK_TAB)
|
||||||
|
{
|
||||||
|
//always reset our completion history so up/down keys will start with new values
|
||||||
|
comp_history_index = -1;
|
||||||
|
|
||||||
|
// we need to build our completion list first
|
||||||
|
if (comp_tab_index == COMPLETION_UNINITIALIZED)
|
||||||
|
{
|
||||||
|
g_completions = [];
|
||||||
|
comp_tab_index = -1;
|
||||||
|
comp_tab_list_offset = 0;
|
||||||
|
comp_tab_startstring = command;
|
||||||
|
|
||||||
|
/* if there is no space between the command name and the cursor
|
||||||
|
* then get completions of the command name
|
||||||
|
*/
|
||||||
|
if(command_line.value.substring(0, command_line.selectionStart).search(/[ \t]/) == -1)
|
||||||
|
{
|
||||||
|
get_command_completions(cmd);
|
||||||
|
}
|
||||||
|
else // dynamically get completions as specified in the g_commands array
|
||||||
|
{
|
||||||
|
var command = get_command(cmd);
|
||||||
|
if (command && command[4])
|
||||||
|
{
|
||||||
|
g_completions = command[4].call(this, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now we have the g_completions, so lets show them */
|
||||||
|
if (comp_tab_index >= -1)
|
||||||
|
{
|
||||||
|
// we could also return when no completion is found
|
||||||
|
// but we fall through to the cleanup anyway
|
||||||
|
if (g_completions.length == 0)
|
||||||
|
beep();
|
||||||
|
|
||||||
|
// show the list
|
||||||
|
completion_show_list();
|
||||||
|
|
||||||
|
if (evt.shiftKey)
|
||||||
|
completion_select_previous_item();
|
||||||
|
else
|
||||||
|
completion_select_next_item();
|
||||||
|
//command_line.focus(); // workaraound only need for RICHlistbox
|
||||||
|
|
||||||
|
|
||||||
|
if (comp_tab_index == -1) // wrapped around matches, reset command line
|
||||||
|
{
|
||||||
|
command_line.value = comp_tab_startstring;
|
||||||
|
completion_list.selectedIndex = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var compl = g_completions[comp_tab_index][0];
|
||||||
|
if (compl)
|
||||||
|
{
|
||||||
|
/* if there is no space between the command name and the cursor
|
||||||
|
* the completions are for the command name
|
||||||
|
*/
|
||||||
|
if(command_line.value.substring(0, command_line.selectionStart).search(/[ \t]/) == -1)
|
||||||
|
{
|
||||||
|
command_line.value = ":" + (count ? count.toString() : "") + compl;
|
||||||
|
}
|
||||||
|
else // completions are for an argument
|
||||||
|
{
|
||||||
|
command_line.value = ":" + (count ? count.toString() : "") +
|
||||||
|
cmd + (special ? "!" : "") + " " + compl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// prevent tab from moving to the next field
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.preventBubble();
|
||||||
|
evt.stopPropagation();
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (evt.keyCode == KeyEvent.DOM_VK_BACK_SPACE)
|
||||||
|
{
|
||||||
|
if (command_line.value == ":")
|
||||||
|
{
|
||||||
|
evt.preventDefault();
|
||||||
|
focusContent(true, true);
|
||||||
|
}
|
||||||
|
comp_tab_index = COMPLETION_UNINITIALIZED;
|
||||||
|
comp_history_index = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// some key hit, check if the cursor is before the :
|
||||||
|
if (command_line.selectionStart == 0)
|
||||||
|
command_line.selectionStart = 1;
|
||||||
|
|
||||||
|
// and reset the tab completion
|
||||||
|
comp_tab_index = COMPLETION_UNINITIALIZED;
|
||||||
|
comp_history_index = -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch(e) { alert(e); }
|
||||||
|
}/*}}}*/
|
||||||
|
|
||||||
|
function onCommandBarInput(event)
|
||||||
|
{
|
||||||
|
if (command_line.value == "")
|
||||||
|
command_line.value = ":";
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
// focus and mode handling //////////////////////////////////////// {{{1
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
/* After pressing Escape, put focus on a non-input field of the browser document */
|
||||||
|
function focusContent(clear_command_line, clear_statusline)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
g_count = -1; // clear count
|
||||||
|
|
||||||
|
if(clear_command_line)
|
||||||
|
{
|
||||||
|
command_line.value = "";
|
||||||
|
command_line.inputField.setAttribute("style","font-family: monospace;");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(clear_statusline)
|
||||||
|
{
|
||||||
|
completion_list.hidden = true;
|
||||||
|
comp_tab_index = COMPLETION_UNINITIALIZED;
|
||||||
|
comp_history_index = -1;
|
||||||
|
updateStatusbar();
|
||||||
|
}
|
||||||
|
|
||||||
|
var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
|
||||||
|
.getService(Components.interfaces.nsIWindowWatcher);
|
||||||
|
if (window == ww.activeWindow && document.commandDispatcher.focusedElement)
|
||||||
|
{
|
||||||
|
document.commandDispatcher.focusedElement.blur();
|
||||||
|
}
|
||||||
|
content.focus();
|
||||||
|
|
||||||
|
} catch(e)
|
||||||
|
{
|
||||||
|
echoerr(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openVimperatorBar(str)
|
||||||
|
{
|
||||||
|
// make sure the input field is not red anymore if we had an echoerr() first
|
||||||
|
command_line.inputField.setAttribute("style","font-family: monospace;");
|
||||||
|
|
||||||
|
if(str == null)
|
||||||
|
str = "";
|
||||||
|
|
||||||
|
if (g_count > 1)
|
||||||
|
command_line.value = ":" + g_count.toString() + str;
|
||||||
|
else
|
||||||
|
command_line.value = ":" + str;
|
||||||
|
|
||||||
|
try {
|
||||||
|
command_line.focus();
|
||||||
|
} catch(e) {
|
||||||
|
echo(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function onEscape()
|
||||||
|
{
|
||||||
|
BrowserStop();
|
||||||
|
focusContent(true, true);
|
||||||
|
hah.disableHahMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onBlur() // FIXME: needed?
|
||||||
|
{
|
||||||
|
//alert('blur');
|
||||||
|
//focusContent(false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
// statusbar/progressbar ////////////////////////////////////////// {{{1
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
/* the statusbar is currently divided into 5 fields, you can set
|
||||||
|
* each one independently */
|
||||||
|
function showStatusbarMessage(msg, field)
|
||||||
|
{
|
||||||
|
var bar = document.getElementById("vim-sb-field-" + field);
|
||||||
|
if (bar)
|
||||||
|
bar.value = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setStatusbarColor(color)
|
||||||
|
{
|
||||||
|
var bar = document.getElementById("vim-statusbar");
|
||||||
|
bar.setAttribute("style", "background-color: " + color);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateStatusbar()
|
||||||
|
{
|
||||||
|
var buffers = "[" + (gBrowser.tabContainer.selectedIndex + 1).toString() + "/" +
|
||||||
|
gBrowser.tabContainer.childNodes.length.toString() + "]";
|
||||||
|
|
||||||
|
showStatusbarMessage(getCurrentLocation(), STATUSFIELD_URL);
|
||||||
|
showStatusbarMessage(" " + g_inputbuffer + " ", STATUSFIELD_INPUTBUFFER);
|
||||||
|
showStatusbarMessage("", STATUSFIELD_PROGRESS);
|
||||||
|
showStatusbarMessage(buffers, STATUSFIELD_BUFFERS);
|
||||||
|
|
||||||
|
// required to postpone it a little, otherwise we could get the wrong cursor
|
||||||
|
// position when switching tabs
|
||||||
|
setTimeout(function() {
|
||||||
|
showStatusbarMessage(createCursorPositionString(), STATUSFIELD_CURSOR_POSITION);
|
||||||
|
} , 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* aProgress is a float between 0 and 1 */
|
||||||
|
function createProgressBar(aProgress)
|
||||||
|
{
|
||||||
|
/* the progress field */
|
||||||
|
var progress;
|
||||||
|
if (aProgress <= 0)
|
||||||
|
progress = "[ Loading... ]";
|
||||||
|
else if (aProgress >= 1)
|
||||||
|
progress = "[====================]";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
progress = /*(aProgress*100).round().toString() + "% */"[";
|
||||||
|
done = Math.floor(aProgress * 20);
|
||||||
|
for (i=0; i < done; i++)
|
||||||
|
progress = progress + "=";
|
||||||
|
progress = progress + ">";
|
||||||
|
for (i=19; i > done; i--)
|
||||||
|
progress = progress + " ";
|
||||||
|
progress = progress + "]";
|
||||||
|
}
|
||||||
|
return progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createCursorPositionString()
|
||||||
|
{
|
||||||
|
var win = document.commandDispatcher.focusedWindow;
|
||||||
|
//var x = win.scrollMaxX == 0 ? 100 : Math.round(win.scrollX / win.scrollMaxX * 100);
|
||||||
|
var y = win.scrollMaxY == 0 ? -1 : Math.round(win.scrollY / win.scrollMaxY * 100);
|
||||||
|
|
||||||
|
var percent;
|
||||||
|
if (y < 0) percent = "All";
|
||||||
|
else if (y == 0) percent = "Top";
|
||||||
|
else if (y < 10) percent = " " + y.toString() + "%";
|
||||||
|
else if (y >= 100) percent = "Bot";
|
||||||
|
else percent = y.toString() + "%";
|
||||||
|
|
||||||
|
return(" " + percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
// text input functions /////////////////////////////////////////// {{{1
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
function isFormElemFocused()
|
||||||
|
{
|
||||||
|
var elt = document.commandDispatcher.focusedElement;
|
||||||
|
if (elt == null) return false;
|
||||||
|
|
||||||
|
var tagName = elt.localName.toUpperCase();
|
||||||
|
|
||||||
|
if (tagName == "INPUT" ||
|
||||||
|
tagName == "TEXTAREA" ||
|
||||||
|
tagName == "SELECT" ||
|
||||||
|
tagName == "BUTTON" ||
|
||||||
|
tagName == "ISINDEX")
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
// logging //////////////////////////////////////////////////////// {{{1
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
var gConsoleService = Components.classes['@mozilla.org/consoleservice;1']
|
||||||
|
.getService(Components.interfaces.nsIConsoleService);
|
||||||
|
|
||||||
|
function logMessage(msg)
|
||||||
|
{
|
||||||
|
gConsoleService.logStringMessage('vimperator: ' + msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
// misc helper funcstions ///////////////////////////////////////// {{{1
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
// this function gets an event as the input and converts it to
|
||||||
|
// a keycode which can be used in mappings
|
||||||
|
// e.g. pressing ctrl+n would result in the string "<c-n>"
|
||||||
|
function keyToString(event)
|
||||||
|
{
|
||||||
|
var key = String.fromCharCode(event.charCode);
|
||||||
|
var modifier = "";
|
||||||
|
if (event.charCode > 0)
|
||||||
|
{
|
||||||
|
if (event.ctrlKey)
|
||||||
|
modifier += "C-";
|
||||||
|
if (event.altKey)
|
||||||
|
modifier += "A-";
|
||||||
|
if (event.metaKey)
|
||||||
|
modifier += "M-";
|
||||||
|
|
||||||
|
if (modifier.length > 0)
|
||||||
|
return "<" + modifier + key + ">";
|
||||||
|
else
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_ESCAPE)
|
||||||
|
return "<Esc>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_RETURN)
|
||||||
|
return "<Return>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_TAB)
|
||||||
|
return "<Tab>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_DELETE)
|
||||||
|
return "<Del>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_BACK_SPACE)
|
||||||
|
return "<BS>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_HOME)
|
||||||
|
return "<Home>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_END)
|
||||||
|
return "<End>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_LEFT)
|
||||||
|
return "<Left>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_RIGHT)
|
||||||
|
return "<Right>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_UP)
|
||||||
|
return "<Up>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_DOWN)
|
||||||
|
return "<Down>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_PAGE_UP)
|
||||||
|
return "<PageUp>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_PAGE_DOWN)
|
||||||
|
return "<PageDown>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_F1)
|
||||||
|
return "<F1>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_F2)
|
||||||
|
return "<F2>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_F3)
|
||||||
|
return "<F3>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_F4)
|
||||||
|
return "<F4>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_F5)
|
||||||
|
return "<F5>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_F6)
|
||||||
|
return "<F6>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_F7)
|
||||||
|
return "<F7>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_F8)
|
||||||
|
return "<F8>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_F9)
|
||||||
|
return "<F9>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_F10)
|
||||||
|
return "<F10>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_F11)
|
||||||
|
return "<F11>";
|
||||||
|
else if (event.keyCode == KeyEvent.DOM_VK_F12)
|
||||||
|
return "<F12>";
|
||||||
|
|
||||||
|
// if nothing matches
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
// DOM related helper functsion /////////////////////////////////// {{{1
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
// Handle frames if they're present
|
||||||
|
function getPageLinkNodes()
|
||||||
|
{
|
||||||
|
var frames = window._content.frames;
|
||||||
|
|
||||||
|
// The main content may have link nodes as well as it's frames.
|
||||||
|
var nodes = getLinkNodes(_content.content.document);
|
||||||
|
var tmp;
|
||||||
|
for (var i=0; i<frames.length; i++) {
|
||||||
|
tmp = getLinkNodes(frames[i].document);
|
||||||
|
// is javascript this crappy?
|
||||||
|
for (var j=0; j<tmp.length; j++)
|
||||||
|
nodes.push(tmp[j]);
|
||||||
|
}
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For a single document, grab all the nodes
|
||||||
|
function getLinkNodes(doc)
|
||||||
|
{
|
||||||
|
var a_nodes = doc.getElementsByTagName('a');
|
||||||
|
var i_nodes = doc.getElementsByTagName('input');
|
||||||
|
var s_nodes = doc.getElementsByTagName('select');
|
||||||
|
var t_nodes = doc.getElementsByTagName('textarea');
|
||||||
|
|
||||||
|
var links = [];
|
||||||
|
|
||||||
|
for (var i=0; i<t_nodes.length; i++) {
|
||||||
|
links.push(t_nodes[i]);
|
||||||
|
}
|
||||||
|
for (var i=0; i<s_nodes.length; i++) {
|
||||||
|
links.push(s_nodes[i]);
|
||||||
|
}
|
||||||
|
for (var i=0; i<i_nodes.length; i++) {
|
||||||
|
if (i_nodes[i].type == "hidden") continue;
|
||||||
|
links.push(i_nodes[i]);
|
||||||
|
}
|
||||||
|
for (var i=0; i<a_nodes.length; i++) {
|
||||||
|
if (!a_nodes[i].hasAttribute('href')) continue;
|
||||||
|
links.push(a_nodes[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return links;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim: set fdm=marker :
|
||||||
96
chrome/content/vimperator/vimperator.xul
Normal file
96
chrome/content/vimperator/vimperator.xul
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||||
|
Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
|
||||||
|
The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
http://www.mozilla.org/MPL/
|
||||||
|
|
||||||
|
Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
for the specific language governing rights and limitations under the
|
||||||
|
License.
|
||||||
|
|
||||||
|
The Initial Developer of the Original Code is Shawn Betts.
|
||||||
|
Portions created by the Initial Developer are Copyright (C) 2004
|
||||||
|
by the Initial Developer. All Rights Reserved.
|
||||||
|
|
||||||
|
Alternatively, the contents of this file may be used under the terms of
|
||||||
|
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
of those above. If you wish to allow use of your version of this file only
|
||||||
|
under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
use your version of this file under the terms of the MPL, indicate your
|
||||||
|
decision by deleting the provisions above and replace them with the notice
|
||||||
|
and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
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.
|
||||||
|
***** END LICENSE BLOCK ***** -->
|
||||||
|
|
||||||
|
<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
|
||||||
|
|
||||||
|
<overlay id="vimperator"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:nc="http://home.netscape.com/NC-rdf#"
|
||||||
|
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||||
|
|
||||||
|
<!-- you may not believe it, but order is really important here -->
|
||||||
|
<script type="application/x-javascript" src="vimperator.js"/>
|
||||||
|
<script type="application/x-javascript" src="commands.js"/>
|
||||||
|
<script type="application/x-javascript" src="settings.js"/>
|
||||||
|
<script type="application/x-javascript" src="completion.js"/>
|
||||||
|
<script type="application/x-javascript" src="bookmarks.js"/>
|
||||||
|
<script type="application/x-javascript" src="hints.js"/>
|
||||||
|
|
||||||
|
<window id="main-window">
|
||||||
|
<toolbar id="vimperator-toolbar" hidden="false" align="center" fullscreentoolbar="true"
|
||||||
|
onblur="onBlur();">
|
||||||
|
<vbox id="vim-container" flex="1" hidden="false">
|
||||||
|
<listbox id="vim-preview_window" class="plain" rows="10" flex="1" hidden="true"
|
||||||
|
ondblclick="preview_window_select(event);" onclick="preview_window_select(event);" onkeydown="preview_window_select(event);"
|
||||||
|
style="font-family: monospace; -moz-user-focus:ignore; overflow:-moz-scrollbars-none;">
|
||||||
|
<listcols>
|
||||||
|
<listcol flex="1" width="50%"/>
|
||||||
|
<listcol flex="1" width="50%"/>
|
||||||
|
</listcols>
|
||||||
|
</listbox>
|
||||||
|
|
||||||
|
<hbox id="vim-statusbar" flex="1" height="10" hidden="false" style="-moz-user-focus:ignore;">
|
||||||
|
<textbox class="plain" id="vim-sb-field-1" flex="1" crop="right" value="about:blank"
|
||||||
|
readonly="true" style="font-family: monospace; background-color: transparent; -moz-user-focus:ignore;"/>
|
||||||
|
<label class="plain" id="vim-sb-field-2" flex="0" crop="right" value="[===> ]"
|
||||||
|
style="font-family: monospace"/>
|
||||||
|
<label class="plain" id="vim-sb-field-3" flex="0" crop="right" value=""
|
||||||
|
style="font-family: monospace"/>
|
||||||
|
<label class="plain" id="vim-sb-field-4" flex="0" crop="right" value="[0/0]"
|
||||||
|
style="font-family: monospace"/>
|
||||||
|
<label class="plain" id="vim-sb-field-5" flex="0" crop="right" value=" Top"
|
||||||
|
style="font-family: monospace"/>
|
||||||
|
</hbox>
|
||||||
|
|
||||||
|
<listbox id="vim-completion" class="plain" rows="1" flex="1" hidden="true"
|
||||||
|
style="font-family: monospace; -moz-user-focus:ignore; -moz-user-select:ignore; overflow:-moz-scrollbars-none;">
|
||||||
|
<listcols>
|
||||||
|
<listcol flex="1" width="50%"/>
|
||||||
|
<listcol flex="1" width="50%"/>
|
||||||
|
</listcols>
|
||||||
|
</listbox>
|
||||||
|
|
||||||
|
<textbox class="plain" id="vim-commandbar" flex="1" hidden="false" type="timed" timeout="100"
|
||||||
|
onkeypress="onCommandBarKeypress(event);" oninput="onCommandBarInput(event);"
|
||||||
|
style="font-family: monospace"/>
|
||||||
|
</vbox>
|
||||||
|
</toolbar>
|
||||||
|
|
||||||
|
<keyset id="mainKeyset">
|
||||||
|
<key id="key_open_vimbar" key=":" oncommand="openVimperatorBar();" modifiers=""/>
|
||||||
|
<key id="key_stop" keycode="VK_ESCAPE" oncommand="onEscape();"/>
|
||||||
|
|
||||||
|
<!-- other keys are handled inside vimperator.js event loop -->
|
||||||
|
</keyset>
|
||||||
|
</window>
|
||||||
|
|
||||||
|
</overlay>
|
||||||
Reference in New Issue
Block a user