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

new vimperator.hints.show() method, DOES NOT work on framed pages for now.

The colors will change later, they are just to see which type of hint it is
This commit is contained in:
Martin Stubenschrott
2007-09-27 12:52:50 +00:00
parent f7714042cf
commit d15fe0a09f
3 changed files with 182 additions and 30 deletions

2
NEWS
View File

@@ -2,6 +2,8 @@
2007-xx-xx:
* version 0.6
* THIS VERSION ONLY WORKS WITH FIREFOX 3.0
* IMPORTANT: changed semantics of :echo and :echoerr: Strings must be quoted with " or ' now,
but you can do things like :echo 3+2 or :echo window.document now
* statusline is now white on black with bold font by default (like in (g)vim)
(change with userChrome.css if you don't like it until we have :colorscheme)
* :let mapleader="," and <Leader> in :map support

View File

@@ -101,30 +101,6 @@ function Hints() //{{{
elem.absoTop = rect.top;
}
return;
//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 if (elem.offsetLeft && elem.offsetTop) // TODO: ugly and broken temporary fix until FF3
//{
// elem.absoLeft = elem.offsetLeft;
// elem.absoTop = elem.offsetTop;
//}
//else
//{
// elem.absoLeft = 0;
// elem.absoTop = 0;
//}
//elem.validCoord = elem.ownerDocument.validCoords;
}
function createHints(win)
@@ -162,6 +138,7 @@ function Hints() //{{{
var hints = hintContainer.childNodes;
var maxhints = vimperator.options["maxhints"];
//vimperator.log("snapshot length: " + res.snapshotLength);
for (i = 0; i < res.snapshotLength; i++)
{
// this saves from script timeouts on pages with some thousand links
@@ -202,10 +179,11 @@ function Hints() //{{{
linkCount++; // and one more total hint
// process firefox event to keep the UI snappy
// if (linkCount % 10 == 0)
// if (linkCount % 50 == 0)
// {
// Components.classes['@mozilla.org/thread-manager;1'].
// getService().mainThread.processNextEvent(false);
// //showHints(null, 0);
// }
}
@@ -214,7 +192,6 @@ function Hints() //{{{
// recursively create hints
for (i = 0; i < win.frames.length; i++)
createHints(win.frames[i]);
}
function showHints(win, off)
@@ -696,12 +673,179 @@ function Hints() //{{{
}
}
window.document.addEventListener("DOMContentLoaded", initDoc, null);
window.document.addEventListener("DOMContentLoaded", function() { vimperator.log("contentloaded"); }, null);
window.addEventListener("load", function() { vimperator.log("load"); }, null);
window.document.addEventListener("pageshow", function() { vimperator.log("pageshow"); }, null);
// window.document.addEventListener("pageshow", function() { vimperator.log("pageshow"); }, null);
// FIXME: add resize support
//window.addEventListener("resize", onResize, null);
getBrowser().addEventListener("DOMContentLoaded", function(event) {
if (vimperator.options["autohints"])
vimperator.hints.show(event.target);
}, false);
this.show = function(doc, takenHints)
{
function getNextHintText(href)
{
var hintCharacters = "abcdefghijklmnopqrstuvwxyz123456789"; // no 0, as it looks too much like O
var len = hintCharacters.length;
var text = "aa";
for (; nextHintFirstChar < len; nextHintFirstChar++)
{
for (; nextHintSecondChar < len; nextHintSecondChar++)
{
text = hintCharacters[nextHintFirstChar] + hintCharacters[nextHintSecondChar];
if (typeof takenHints[text] === "undefined")
{
takenHints[text] = href;
return text.toUpperCase();
}
}
nextHintSecondChar = 0;
}
vimperator.log("Too many hints on page");
return null;
}
if (!doc)
doc = window.content.document;
if (!takenHints)
takenHints = {};
var rel = 0, abs = 0, inl = 0;
var nextHintFirstChar = 0, nextHintSecondChar = 0;
var finder = Components.classes["@mozilla.org/embedcomp/rangefind;1"]
.createInstance()
.QueryInterface(Components.interfaces.nsIFind);
finder.caseSensitive = false;
var baseNodeInline = doc.createElementNS("http://www.w3.org/1999/xhtml", "span");
baseNodeInline.style.backgroundColor = "#BCEE68";
baseNodeInline.style.color = "black";
baseNodeInline.style.display = "inline";
baseNodeInline.style.fontSize = "inherit";
baseNodeInline.style.padding = "0";
baseNodeInline.className = "vimperator-hint-inline";
var baseNodeAbsolute = doc.createElementNS("http://www.w3.org/1999/xhtml", "span");
//baseNodeAbsolute.style.backgroundColor = "#BCEE68";
baseNodeAbsolute.style.backgroundColor = "cyan";
baseNodeAbsolute.style.color = "black";
baseNodeAbsolute.style.position = "absolute";
baseNodeAbsolute.style.fontSize = "9px";
baseNodeAbsolute.style.fontWeight = "bold";
//baseNodeAbsolute.style.fontFamily = "monospace";
baseNodeAbsolute.style.lineHeight = "9px";
baseNodeAbsolute.style.padding = "0px 1px 0px 1px";
baseNodeAbsolute.style.zIndex = "5000";
baseNodeAbsolute.className = "vimperator-hint-absolute";
var scrollX = doc.defaultView.scrollX;
var scrollY = doc.defaultView.scrollY;
//var view = doc.defaultView;
var retRange = null;
var searchRange = doc.createRange();
var res = vimperator.buffer.evaluateXPath(vimperator.options["hinttags"], doc);
var word, elem, count, href, text, lowertext;
vimperator.log("Hinting " + res.snapshotLength + " items on " + doc.title);
outer:
for (var i = 0; i < res.snapshotLength; i++)
{
// the more often we check for firefox events, the slower it is
// best is checking between every 50-500 elements
if (i % 200 == 0)
{
Components.classes['@mozilla.org/thread-manager;1'].
getService().mainThread.processNextEvent(true);
// update saved positions, as the user could have scrolled
scrollX = doc.defaultView.scrollX;
scrollY = doc.defaultView.scrollY;
vimperator.log(scrollY);
}
elem = res.snapshotItem(i);
count = elem.childNodes.length;
searchRange.setStart(elem, 0);
searchRange.setEnd(elem, count);
// try to get a unique substring of the element
text = elem.textContent; // faster than searchRange.toString()
href = elem.getAttribute("href");
for (var j = 0; j < text.length - 1; j++)
{
if (text.length < 2)
continue;
word = text.substr(j, 2);
lowertext = word.toLowerCase();
if (/[^a-z0-9]/.test(lowertext)) // 2x as fast as lowertext[0] > "a" etc. testing
continue;
if (typeof(takenHints[lowertext]) === "undefined" ||
(href && takenHints[lowertext] == href))
{ // hint not yet taken or taken and href the same
takenHints[lowertext] = href;
inl++;
retRange = finder.Find(word, searchRange, searchRange, searchRange);
if (!retRange)
{
dump("no retRange for: " + word + "\n");
continue;
}
var nodeSurround = baseNodeInline.cloneNode(true);
var startContainer = retRange.startContainer;
var startOffset = retRange.startOffset;
var docfrag = retRange.extractContents();
var before = startContainer.splitText(startOffset);
var parent = before.parentNode;
nodeSurround.appendChild(docfrag);
parent.insertBefore(nodeSurround, before);
continue outer;
}
}
// if we came here, there was no suitable inline hint, need
// to create an absolutely positioned div
var lower = elem.tagName.toLowerCase();
if (lower != "input" && lower != "textarea")
{
elem.style.position = "relative";
rel++;
var span = doc.createElement("span");
span.setAttribute("style", "z-index: 5000; color:black; font-weight: bold; font-size: 9px; background-color:yellow; line-height: 9px; border: 0px; padding: 0px 1px 0px 1px; position: absolute; left: 0px; top: 0px");
var hint = getNextHintText(href);
if (!hint)
return false;
span.innerHTML = hint;
//setTimeout(function() { elem.appendChild(span); }, 10); // 10ms delay to let firefox handle position=relative
elem.appendChild(span);
continue;
}
else
{
var rect = elem.getClientRects()[0];
if (rect)
{
var span = baseNodeAbsolute.cloneNode(true);
var hint = getNextHintText(href);
if (!hint)
return false;
span.innerHTML = hint;
span.style.left = rect.left + scrollX + "px";
span.style.top = rect.top + scrollY + "px";
doc.body.appendChild(span);
abs++;
}
}
}
vimperator.log("Done hinting " + res.snapshotLength + " items on " + doc.title);
vimperator.log("REL: " + rel + " - ABS: " + abs + " - INL: " + inl);
return true;
}
} //}}}
// vim: set fdm=marker sw=4 ts=4 et:

View File

@@ -356,6 +356,12 @@ function Options() //{{{
default_value: "homepage,quickmark,tabopen,paste"
}
));
addOption(new Option(["autohints", "ah"], "boolean",
{
short_help: "Automatically show hints on every web page",
default_value: false
}
));
addOption(new Option(["complete", "cpt"], "charlist",
{
short_help: "Items which are completed at the :[tab]open prompt",