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

Fix favcons in completions, add "shutdown" trigger, register vimperator.css as user stylesheet, make option completions better, hide completion list when no completions available. Yeah. A lot. Sorry.

This commit is contained in:
Kris Maglione
2008-10-05 03:50:09 +00:00
parent 506838b41d
commit 55df63ee81
13 changed files with 157 additions and 170 deletions

View File

@@ -184,6 +184,9 @@ liberator.Bookmarks = function () //{{{
}
var cache = liberator.storage.newObject("bookmark-cache", Cache, false);
liberator.storage.addObserver("bookmark-cache", bookmarkObserver);
liberator.registerCallback("shutdown", 0, function () {
liberator.storage.removeObserver("bookmark-cache", bookmarkObserver)
});
/////////////////////////////////////////////////////////////////////////////}}}
////////////////////// OPTIONS /////////////////////////////////////////////////
@@ -416,11 +419,11 @@ liberator.Bookmarks = function () //{{{
{
var searchEngines = [];
var firefoxEngines = searchService.getVisibleEngines({});
for (let i in firefoxEngines)
for (let [,engine] in Iterator(firefoxEngines))
{
var alias = firefoxEngines[i].alias;
var alias = engine.alias;
if (!alias || !/^[a-z0-9_-]+$/.test(alias))
alias = firefoxEngines[i].name.replace(/^\W*([a-zA-Z_-]+).*/, "$1").toLowerCase();
alias = engine.name.replace(/^\W*([a-zA-Z_-]+).*/, "$1").toLowerCase();
if (!alias)
alias = "search"; // for search engines which we can't find a suitable alias
@@ -434,10 +437,10 @@ liberator.Bookmarks = function () //{{{
newAlias = alias + j;
}
// only write when it changed, writes are really slow
if (firefoxEngines[i].alias != newAlias)
firefoxEngines[i].alias = newAlias;
if (engine.alias != newAlias)
engine.alias = newAlias;
searchEngines.push([firefoxEngines[i].alias, firefoxEngines[i].description]);
searchEngines.push([engine.alias, engine.description, engine.iconURI.spec]);
}
return searchEngines;
@@ -501,15 +504,10 @@ liberator.Bookmarks = function () //{{{
url: item[0],
title: item[1],
extra: [['keyword', item[2], 'red'],
['tags', item[3].join(', '), 'blue']].filter(function (i) i[1])
['tags', (item[3]||[]).join(', '), 'blue']].filter(function (i) i[1])
} for each (item in items)));
liberator.commandline.echo(list, liberator.commandline.HL_NORMAL, liberator.commandline.FORCE_MULTILINE);
},
destroy: function ()
{
liberator.storage.removeObserver("bookmark-cache", bookmarkObserver);
}
};
//}}}
}; //}}}

View File

@@ -38,11 +38,13 @@ liberator.Buffer = function () //{{{
120, 150, 200, 300, 500, 1000, 2000 ];
const arrayIter = liberator.util.arrayIter;
/* Can't reference liberator inside Styles --
* it's a global object, and liberator disappears
/* Can't reference liberator or Components inside Styles --
* they're members of the window object, which disappear
* with this window.
*/
const util = liberator.util;
const consoleService = Components.classes["@mozilla.org/consoleservice;1"]
.getService(Components.interfaces.nsIConsoleService);
function Styles(name, store, serial)
{
@@ -143,13 +145,10 @@ liberator.Buffer = function () //{{{
}
};
var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
.getService(Components.interfaces.nsIConsoleService);
consoleService.registerListener(listener);
try
{
var doc = document.implementation.createDocument(XHTML, "doc", null);
consoleService.registerListener(listener);
let doc = document.implementation.createDocument(XHTML, "doc", null);
doc.documentElement.appendChild(util.xmlToDom(
<html><head><link type="text/css" rel="stylesheet" href={cssUri(css)}/></head></html>, doc));
@@ -182,6 +181,16 @@ liberator.Buffer = function () //{{{
let styles = liberator.storage.newObject("styles", Styles, false);
/* FIXME: This doesn't belong here. */
let mainWindowID = liberator.config.mainWindowID || "main-window";
let fontSize = document.defaultView.getComputedStyle(document.getElementById(mainWindowID), null)
.getPropertyValue("font-size");
let name = liberator.config.name.toLowerCase();
styles.registerSheet("chrome://" + name + "/skin/vimperator.css");
let error = styles.addSheet("chrome://" + name + "/content/buffer.xhtml",
"body { font-size: " + fontSize + "}");
function setZoom(value, fullZoom)
{
if (value < 1 || value > 2000)

View File

@@ -4,8 +4,6 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title/>
<link rel="stylesheet" type="text/css"
href="chrome://muttator/skin/vimperator.css"/>
</head>
<body/>
</html>

View File

@@ -49,10 +49,43 @@ liberator.Completion = function () //{{{
//let foo = ["", "IGNORED", "FAILURE", "NOMATCH", "SUCCESS", "NOMATCH_ONGOING", "SUCCESS_ONGOING"];
liberator.commandline.setCompletions(completionCache.concat(comp));
historyCache = comp;
historyCache = comp.map(addIcon);
liberator.commandline.setCompletions(completionCache.concat(historyCache));
});
const faviconService = Components.classes["@mozilla.org/browser/favicon-service;1"]
.getService(Components.interfaces.nsIFaviconService);
const ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
function getIcon(uri)
{
try
{
let img = faviconService.getFaviconImageForPage(ioService.newURI(uri, null, null));
return img.spec;
}
catch (e) {}
}
function addIcon(elem)
{
return [elem[0], elem[1], getIcon(elem[0])];
}
function buildSubstrings(str, filter)
{
if (filter == "")
return;
let length = filter.length;
let start = 0;
let idx;
while ((idx = str.indexOf(filter, start)) > -1)
{
for (let end in liberator.util.range(idx + length, str.length + 1))
substrings.push(str.substring(idx, end));
start = idx + 1;
}
}
// function uses smartcase
// list = [ [['com1', 'com2'], 'text'], [['com3', 'com4'], 'text'] ]
function buildLongestCommonSubstring(list, filter)
@@ -67,36 +100,26 @@ liberator.Completion = function () //{{{
if (liberator.options["wildmode"].indexOf("longest") >= 0)
longest = true;
for (let i = 0; i < list.length; i++)
for (let [,item] in Iterator(list))
{
var complist = list[i][0] instanceof Array ? list[i][0] : [list[i][0]];
for (let j = 0; j < complist.length; j++)
var complist = item[0] instanceof Array ? item[0]
: [item[0]];
for (let [,compitem] in Iterator(complist))
{
var item = String(complist[j]);
if (ignorecase)
item = item.toLowerCase();
compitem = String.toLowerCase(compitem);
if (item.indexOf(filter) == -1)
if (compitem.indexOf(filter) == -1)
continue;
filtered.push([complist[j], list[i][1]]);
filtered.push([compitem, item[1], item[2]]);
if (longest)
{
if (substrings.length == 0)
{
var lastIndex = item.lastIndexOf(filter);
var length = item.length;
for (let k = item.indexOf(filter); k != -1 && k <= lastIndex; k = item.indexOf(filter, k + 1))
{
for (let l = k + filter.length; l <= length; l++)
substrings.push(complist[j].substring(k, l));
}
}
buildSubstrings(compitem, filter);
else
{
substrings = substrings.filter(function (s) complist[j].indexOf(s) >= 0);
}
substrings = substrings.filter(function (s) compitem.indexOf(s) >= 0);
}
break;
}
@@ -113,27 +136,28 @@ liberator.Completion = function () //{{{
if (liberator.options["wildmode"].indexOf("longest") >= 0)
longest = true;
for (let i = 0; i < list.length; i++)
for (let [,item] in Iterator(list))
{
var complist = list[i][0] instanceof Array ? list[i][0] : [list[i][0]];
for (let j = 0; j < complist.length; j++)
var complist = item[0] instanceof Array ? item[0]
: [item[0]];
for (let [,compitem] in Iterator(complist))
{
if (complist[j].indexOf(filter) != 0)
if (compitem.indexOf(filter) != 0)
continue;
filtered.push([complist[j], list[i][1]]);
filtered.push([compitem, item[1], item[2]]);
if (longest)
{
if (substrings.length == 0)
{
var length = complist[j].length;
var length = compitem.length;
for (let k = filter.length; k <= length; k++)
substrings.push(complist[j].substring(0, k));
substrings.push(compitem.substring(0, k));
}
else
{
substrings = substrings.filter(function (s) complist[j].indexOf(s) == 0);
substrings = substrings.filter(function (s) compitem.indexOf(s) == 0);
}
}
break;
@@ -266,7 +290,8 @@ liberator.Completion = function () //{{{
}
mapped = files.map(function (file) [tail ? file.leafName : (dir + file.leafName),
file.isDirectory() ? "Directory" : "File"]);
file.isDirectory() ? "Directory" : "File",
getIcon("file://" + file.path)]);
}
catch (e)
{
@@ -366,8 +391,9 @@ liberator.Completion = function () //{{{
search: function (filter)
{
var engines = liberator.bookmarks.getSearchEngines().concat(liberator.bookmarks.getKeywords());
return [0, this.filter(engines, filter)];
var keywords = [[k[0], k[1], getIcon(k[2])] for each (k in liberator.bookmarks.getKeywords())];
var engines = liberator.bookmarks.getSearchEngines();
return [0, this.filter(engines.concat(keywords), filter)];
},
// XXX: Move to bookmarks.js?
@@ -464,18 +490,17 @@ liberator.Completion = function () //{{{
for (let c in liberator.util.arrayIter(cpt))
{
if (c == "s")
completions = completions.concat(this.search(filter)[1]);
completions.push(this.search(filter)[1]);
else if (c == "f")
completions = completions.concat(this.file(filter, false)[1]);
completions.push(this.file(filter, false)[1]);
else if (c == "S")
completions = completions.concat(this.searchEngineSuggest(filter, suggestEngineAlias)[1]);
completions.push(this.searchEngineSuggest(filter, suggestEngineAlias)[1]);
else if (c == "b" && !autoCompletions)
completions = completions.concat(liberator.bookmarks.get(filter));
completions.push(liberator.bookmarks.get(filter).map(addIcon));
else if (c == "h" && !autoCompletions)
completions = completions.concat(liberator.history.get(filter));
completions.push(liberator.history.get(filter).map(addIcon));
else if (c == "l") // add completions like Firefox's smart location bar
{
completionCache = completions;
completionService.startSearch(filter, "", historyResult, {
onSearchResult: function (search, result) {
historyResult = result;
@@ -487,7 +512,8 @@ liberator.Completion = function () //{{{
}
}
return [start, completions.concat(historyCache)];
completionCache = liberator.util.flatten(completions);
return [start, completionCache.concat(historyCache)];
},
userCommand: function (filter)
@@ -515,7 +541,7 @@ liberator.Completion = function () //{{{
{
var filtered = [];
// completions which don't match the url but just the description
// list them add the end of the array
// list them at the end of the array
var additionalCompletions = [];
if (urls.length == 0)
@@ -529,7 +555,7 @@ liberator.Completion = function () //{{{
filterTags = filterTags || [];
// TODO: use ignorecase and smartcase settings
var ignorecase = (filter == filter.toLowerCase() && filterTags.join(",") == filterTags.join(",").toLowerCase());
var ignorecase = (filter == filter.toLowerCase() && filterTags.every(function (t) t == t.toLowerCase()));
if (ignorecase)
{
@@ -540,12 +566,12 @@ liberator.Completion = function () //{{{
// Longest Common Subsequence
// This shouldn't use buildLongestCommonSubstring for performance
// reasons, so as not to cycle through the urls twice
let filterTokens = filter.split(/\s+/);
for (let [,elem] in Iterator(urls))
{
var url = elem[0] || "";
var title = elem[1] || "";
var tags = elem[3] || [];
if (ignorecase)
{
url = url.toLowerCase();
@@ -561,32 +587,17 @@ liberator.Completion = function () //{{{
{
// no direct match of filter in the url, but still accept this item
// if _all_ tokens of filter match either the url or the title
if (filter.split(/\s+/).every(
function (token) url.indexOf(token) > -1 || title.indexOf(token) > -1
))
if (filterTokens.every(function (token) url.indexOf(token) > -1 || title.indexOf(token) > -1))
additionalCompletions.push(elem);
continue;
}
// TODO: refactor out? And just build if wildmode contains longest?
// Of course --Kris
if (substrings.length == 0) // Build the substrings
{
var lastIndex = url.lastIndexOf(filter);
var urlLength = url.length;
if (lastIndex >= 0 && lastIndex < urlLength) // do not build substrings, if we don't match filter
{
for (let k = url.indexOf(filter); k != -1 && k <= lastIndex; k = url.indexOf(filter, k + 1))
{
for (let l = k + filter.length; l <= urlLength; l++)
substrings.push(url.substring(k, l));
}
}
}
buildSubstrings(url, filter);
else
{
substrings = substrings.filter(function (s) url.indexOf(s) >= 0);
}
filtered.push(elem);
}

View File

@@ -1603,6 +1603,7 @@ liberator.Events = function () //{{{
catch (e) {}
eventManager.prefObserver.register();
liberator.registerCallback("shutdown", 0, eventManager.destroy);
window.addEventListener("keypress", eventManager.onKeyPress, true);
window.addEventListener("keydown", eventManager.onKeyUpOrDown, true);

View File

@@ -87,9 +87,8 @@ liberator.Hints = function () //{{{
var scrollX = doc.defaultView.scrollX;
var scrollY = doc.defaultView.scrollY;
var baseNodeAbsolute = doc.createElementNS("http://www.w3.org/1999/xhtml", "span");
baseNodeAbsolute.style.cssText = liberator.options["hintstyle"];
baseNodeAbsolute.className = "liberator-hint";
var baseNodeAbsolute = liberator.util.xmlToDom(
<span style={liberator.options["hintstyle"]} class="liberator-hint"/>, doc);
var elem, tagname, text, span, rect;
var res = liberator.buffer.evaluateXPath(liberator.options["hinttags"], doc, null, true);

View File

@@ -627,7 +627,7 @@ const liberator = (function () //{{{
for (let i = 0; i < callbacks.length; i++)
{
var [thistype, thismode, thisfunc] = callbacks[i];
if (mode == thismode && type == thistype)
if (mode == liberator.modes.NONE || mode == thismode && type == thistype)
return thisfunc.call(this, data);
}
return false;
@@ -1077,10 +1077,10 @@ const liberator = (function () //{{{
loadModule("commands", liberator.Commands); addCommands();
loadModule("options", liberator.Options); addOptions();
loadModule("mappings", liberator.Mappings); addMappings();
loadModule("buffer", liberator.Buffer);
loadModule("events", liberator.Events);
loadModule("commandline", liberator.CommandLine);
loadModule("statusline", liberator.StatusLine);
loadModule("buffer", liberator.Buffer);
loadModule("editor", liberator.Editor);
loadModule("autocommands", liberator.AutoCommands);
loadModule("io", liberator.IO);
@@ -1181,11 +1181,7 @@ const liberator = (function () //{{{
liberator.storage.saveAll();
// save our preferences
liberator.options.destroy();
liberator.events.destroy();
if (liberator.has("bookmarks"))
liberator.bookmarks.destroy();
liberator.triggerCallback("shutdown", 0, null);
liberator.dump("All liberator modules destroyed\n");

View File

@@ -174,6 +174,9 @@ liberator.Options = function () //{{{
liberator.storage.newMap("options", false);
liberator.storage.addObserver("options", optionObserver);
liberator.registerCallback("shutdown", 0, function () {
liberator.storage.removeObserver("options", optionObserver)
});
function storePreference(name, value)
{
@@ -247,7 +250,15 @@ liberator.Options = function () //{{{
// work around firefox popup blocker
var popupAllowedEvents = loadPreference("dom.popup_allowed_events", "change click dblclick mouseup reset submit");
if (!/keypress/.test(popupAllowedEvents))
{
storePreference("dom.popup_allowed_events", popupAllowedEvents + " keypress");
liberator.registerCallback("shutdown", 0, function ()
{
if (loadPreference("dom.popup_allowed_events", "")
== popupAllowedEvents + " keypress")
storePreference("dom.popup_allowed_events", popupAllowedEvents);
});
}
// TODO: maybe reset in .destroy()?
// TODO: move to vim.js or buffer.js
@@ -801,10 +812,15 @@ liberator.Options = function () //{{{
len = filter.length - len;
filter = filter.substr(len);
if (!completer)
return [len, [[option.value, ""]]];
let completions = completer(filter);
/* Not vim compatible, but is a significant enough improvement
* that it's worth breaking compatibility.
*/
let completions = [];
if (!opt.value)
completions = [[option.value, "Current value"], [option.defaultValue, "Default value"]].filter(function (f) f[0]);
if (completer)
{
completions = completions.concat(completer(filter));
if (have)
{
completions = completions.filter(function (val) have2.indexOf(val[0]) == -1);
@@ -818,6 +834,7 @@ liberator.Options = function () //{{{
break;
}
}
}
return [len, liberator.completion.filter(completions, filter, true)];
}
});
@@ -896,15 +913,6 @@ liberator.Options = function () //{{{
return true;
},
destroy: function ()
{
// reset some modified firefox prefs
if (loadPreference("dom.popup_allowed_events", "change click dblclick mouseup reset submit")
== popupAllowedEvents + " keypress")
storePreference("dom.popup_allowed_events", popupAllowedEvents);
liberator.storage.removeObserver("options", optionObserver);
},
get: function (name, scope)
{
if (!scope)

View File

@@ -121,8 +121,7 @@ liberator.CommandLine = function () //{{{
// the widget used for multiline output
var multilineOutputWidget = document.getElementById("liberator-multiline-output");
multilineOutputWidget.setAttribute("src",
liberator.util.blankDocument("liberator-multiline-output-content"));
liberator.util.blankDocument(multilineOutputWidget, "liberator-multiline-output-content");
var outputContainer = multilineOutputWidget.parentNode;
@@ -225,7 +224,6 @@ liberator.CommandLine = function () //{{{
if (outputContainer.collapsed)
doc.body.innerHTML = "";
XML.prettyPrinting = false;
doc.body.appendChild(liberator.util.xmlToDom(output, doc));
var availableHeight = 250;
@@ -824,8 +822,6 @@ liberator.CommandLine = function () //{{{
completionIndex = 0;
}
// FIXME: this innocent looking line is the source of a big performance
// problem, when keeping <Tab> pressed down, so disable it for now
statusTimer.tell();
}
@@ -1131,6 +1127,9 @@ liberator.CommandLine = function () //{{{
if (liberator.mode != liberator.modes.COMMAND_LINE)
return;
if (compl.length == 0)
return completionList.hide();
completionList.setItems(compl);
if (completionIndex >= 0 && completionIndex < compl.length && completionIndex < completions.length)
@@ -1193,32 +1192,16 @@ liberator.ItemList = function (id) //{{{
var doc;
var container = iframe.parentNode;
iframe.setAttribute("src", liberator.util.blankDocument(id + "-content"));
liberator.util.blankDocument(iframe, id + "-content");
var completions = []; // a reference to the Array of completions
var listOffset = -1; // how many items is the displayed list shifted from the internal tab index
var listIndex = -1; // listOffset + listIndex = completions[item]
var selectedElement = null;
// FIXME: ItemList shouldn't know of favicons of course, so also temporary
try
{
var faviconService = Components.classes["@mozilla.org/browser/favicon-service;1"].getService(Components.interfaces.nsIFaviconService);
const ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
}
catch (e) {} // for muttator!
// TODO: temporary, to be changed/removed
function createRow(b, c, dom)
function createRow(b, c, a, dom)
{
try
{
let uri = ioService.newURI(b, null, null);
var a = faviconService.getFaviconImageForPage(uri).spec;
}
catch (e) {}
let row =
<tr class="liberator-compitem">
<td style="width: 16px"/>
@@ -1266,8 +1249,9 @@ liberator.ItemList = function (id) //{{{
if (listIndex > -1 && offset == listOffset + 1)
{
let item = completions[offset + maxItems - 1];
listOffset = offset;
var row = createRow(completions[offset + maxItems - 1][0], completions[offset + maxItems - 1][1], true);
var row = createRow(item[0], item[1], item[2], true);
var e = doc.getElementsByTagName("tbody");
e = e[e.length - 1];
@@ -1278,8 +1262,9 @@ liberator.ItemList = function (id) //{{{
}
else if (listIndex > -1 && offset == listOffset - 1)
{
let item = completions[offset];
listOffset = offset;
var row = createRow(completions[offset][0], completions[offset][1], true);
var row = createRow(item[0], item[1], item[2], true);
var e = doc.getElementsByTagName("tbody");
e = e[e.length - 1];
@@ -1294,6 +1279,7 @@ liberator.ItemList = function (id) //{{{
// do a full refill of the list:
doc.body.innerHTML = "";
XML.ignoreWhitespace = true;
let div = <div class="ex-command-output hl-Normal">
<span class="hl-Title" style="font-weight: bold">Completions:</span>
<table width="100%" style="table-layout: fixed; width: 100%"><tbody/></table>
@@ -1304,7 +1290,7 @@ liberator.ItemList = function (id) //{{{
completions.length)))
{
let elem = completions[i];
tbody.* += createRow(elem[0], elem[1]);
tbody.* += createRow(elem[0], elem[1], elem[2]);
}
doc.body.appendChild(liberator.util.xmlToDom(div, doc));

View File

@@ -77,22 +77,10 @@ liberator.util = { //{{{
yield ary[i];
},
blankDocument: function (bodyId)
blankDocument: function (iframe, bodyId)
{
let mainWindowID = liberator.config.mainWindowID || "main-window";
let fontSize = document.defaultView.getComputedStyle(document.getElementById(mainWindowID), null)
.getPropertyValue("font-size");
return 'data:application/xhtml+xml,' + encodeURI('<?xml version="1.0" encoding="UTF-8"?>' +
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">' +
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title/>
<link rel="stylesheet" type="text/css"
href={"chrome://" + liberator.config.name.toLowerCase() + "/skin/vimperator.css"}/>
</head>
<body id={bodyId} style={"font-size: " + fontSize}/>
</html>)
iframe.addEventListener("load", function () { iframe.contentDocument.body.setAttribute("id", bodyId) }, true);
iframe.setAttribute("src", "chrome://" + liberator.config.name.toLowerCase() + "/content/buffer.xhtml");
},
clip: function (str, length)
@@ -444,6 +432,7 @@ liberator.util = { //{{{
xmlToDom: function (node, doc)
{
XML.prettyPrinting = false;
switch (node.nodeKind())
{
case "text":

View File

@@ -110,10 +110,6 @@ liberator.config = { //{{{
"message.html", "developer.html", "various.html", "index.html"
],
userSheets: [
"chrome://vimperator/skin/content.css",
],
init: function ()
{
function incrementURL(count)

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title/>
<link rel="stylesheet" type="text/css"
href="chrome://vimperator/skin/vimperator.css"/>
</head>
<body/>
</html>

View File

@@ -26,6 +26,11 @@ 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 *****/
@-moz-document
url-prefix(chrome://vimperator/),
url-prefix(chrome://muttator/),
url(chrome://browser/content/browser.xul) {
#liberator-container {
font-family: monospace;
}
@@ -207,4 +212,6 @@ a.hl-URL:hover {
border: 0px;
}
}
/* vim: set fdm=marker sw=4 ts=4 et: */