mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2026-03-16 18:13:32 +01:00
heuristics to avoid duplicate relative hints
This commit is contained in:
@@ -163,12 +163,14 @@ function Buffer() //{{{
|
|||||||
this.lastInputField = null; // used to keep track of the right field for "gi"
|
this.lastInputField = null; // used to keep track of the right field for "gi"
|
||||||
|
|
||||||
// returns an XPathResult object
|
// returns an XPathResult object
|
||||||
this.evaluateXPath = function(expression, doc, ordered)
|
this.evaluateXPath = function(expression, doc, elem, ordered)
|
||||||
{
|
{
|
||||||
if (!doc)
|
if (!doc)
|
||||||
doc = window.content.document;
|
doc = window.content.document;
|
||||||
|
if (!elem)
|
||||||
|
elem = doc;
|
||||||
|
|
||||||
var result = doc.evaluate(expression, doc,
|
var result = doc.evaluate(expression, elem,
|
||||||
function lookupNamespaceURI(prefix) {
|
function lookupNamespaceURI(prefix) {
|
||||||
switch (prefix) {
|
switch (prefix) {
|
||||||
case 'xhtml':
|
case 'xhtml':
|
||||||
|
|||||||
@@ -711,7 +711,7 @@ function Hints() //{{{
|
|||||||
if (!takenHints)
|
if (!takenHints)
|
||||||
takenHints = {};
|
takenHints = {};
|
||||||
|
|
||||||
var rel = 0, abs = 0, inl = 0;
|
var rel = 0, abs = 0, inl = 0, disc = 0;
|
||||||
var nextHintFirstChar = 0, nextHintSecondChar = 0;
|
var nextHintFirstChar = 0, nextHintSecondChar = 0;
|
||||||
|
|
||||||
var finder = Components.classes["@mozilla.org/embedcomp/rangefind;1"]
|
var finder = Components.classes["@mozilla.org/embedcomp/rangefind;1"]
|
||||||
@@ -724,18 +724,17 @@ function Hints() //{{{
|
|||||||
baseNodeInline.style.color = "black";
|
baseNodeInline.style.color = "black";
|
||||||
baseNodeInline.style.display = "inline";
|
baseNodeInline.style.display = "inline";
|
||||||
baseNodeInline.style.fontSize = "inherit";
|
baseNodeInline.style.fontSize = "inherit";
|
||||||
baseNodeInline.style.padding = "0";
|
baseNodeInline.style.padding = "0px";
|
||||||
baseNodeInline.className = "vimperator-hint-inline";
|
baseNodeInline.className = "vimperator-hint-inline";
|
||||||
var baseNodeAbsolute = doc.createElementNS("http://www.w3.org/1999/xhtml", "span");
|
var baseNodeAbsolute = doc.createElementNS("http://www.w3.org/1999/xhtml", "span");
|
||||||
//baseNodeAbsolute.style.backgroundColor = "#BCEE68";
|
//baseNodeAbsolute.style.backgroundColor = "#BCEE68";
|
||||||
baseNodeAbsolute.style.backgroundColor = "cyan";
|
baseNodeAbsolute.style.backgroundColor = "cyan";
|
||||||
baseNodeAbsolute.style.color = "black";
|
baseNodeAbsolute.style.color = "black";
|
||||||
baseNodeAbsolute.style.position = "absolute";
|
baseNodeAbsolute.style.position = "absolute";
|
||||||
baseNodeAbsolute.style.fontSize = "9px";
|
baseNodeAbsolute.style.fontSize = "10px";
|
||||||
baseNodeAbsolute.style.fontWeight = "bold";
|
baseNodeAbsolute.style.fontWeight = "bold";
|
||||||
//baseNodeAbsolute.style.fontFamily = "monospace";
|
baseNodeAbsolute.style.lineHeight = "10px";
|
||||||
baseNodeAbsolute.style.lineHeight = "9px";
|
baseNodeAbsolute.style.padding = "0px 1px 0px 0px";
|
||||||
baseNodeAbsolute.style.padding = "0px 1px 0px 1px";
|
|
||||||
baseNodeAbsolute.style.zIndex = "5000";
|
baseNodeAbsolute.style.zIndex = "5000";
|
||||||
baseNodeAbsolute.className = "vimperator-hint-absolute";
|
baseNodeAbsolute.className = "vimperator-hint-absolute";
|
||||||
|
|
||||||
@@ -745,8 +744,8 @@ function Hints() //{{{
|
|||||||
|
|
||||||
var retRange = null;
|
var retRange = null;
|
||||||
var searchRange = doc.createRange();
|
var searchRange = doc.createRange();
|
||||||
var res = vimperator.buffer.evaluateXPath(vimperator.options["hinttags"], doc);
|
var res = vimperator.buffer.evaluateXPath(vimperator.options["hinttags"], doc, null, true);
|
||||||
var word, elem, count, href, text, lowertext;
|
var word, elem, tagname, count, href, text, lowertext;
|
||||||
vimperator.log("Hinting " + res.snapshotLength + " items on " + doc.title);
|
vimperator.log("Hinting " + res.snapshotLength + " items on " + doc.title);
|
||||||
outer:
|
outer:
|
||||||
for (var i = 0; i < res.snapshotLength; i++)
|
for (var i = 0; i < res.snapshotLength; i++)
|
||||||
@@ -756,7 +755,7 @@ outer:
|
|||||||
if (i % 200 == 0)
|
if (i % 200 == 0)
|
||||||
{
|
{
|
||||||
Components.classes['@mozilla.org/thread-manager;1'].
|
Components.classes['@mozilla.org/thread-manager;1'].
|
||||||
getService().mainThread.processNextEvent(true);
|
getService().mainThread.processNextEvent(false);
|
||||||
|
|
||||||
// update saved positions, as the user could have scrolled
|
// update saved positions, as the user could have scrolled
|
||||||
scrollX = doc.defaultView.scrollX;
|
scrollX = doc.defaultView.scrollX;
|
||||||
@@ -765,12 +764,24 @@ outer:
|
|||||||
}
|
}
|
||||||
|
|
||||||
elem = res.snapshotItem(i);
|
elem = res.snapshotItem(i);
|
||||||
|
tagname = elem.tagName.toLowerCase();
|
||||||
|
|
||||||
|
|
||||||
|
//if (vimperator.buffer.evaluateXPath(".//*[@class='vimperator-hint-inline']", doc, elem).snapshotLength > 0 )
|
||||||
|
// continue outer;
|
||||||
|
if (elem.getElementsByClassName("vimperator-hint-inline").length > 0)
|
||||||
|
continue outer;
|
||||||
|
|
||||||
count = elem.childNodes.length;
|
count = elem.childNodes.length;
|
||||||
searchRange.setStart(elem, 0);
|
searchRange.setStart(elem, 0);
|
||||||
searchRange.setEnd(elem, count);
|
searchRange.setEnd(elem, count);
|
||||||
|
|
||||||
// try to get a unique substring of the element
|
// try to get a unique substring of the element
|
||||||
text = elem.textContent; // faster than searchRange.toString()
|
if (tagname == "input" || tagname == "textarea" || tagname == "select")
|
||||||
|
text = "";
|
||||||
|
else
|
||||||
|
text = elem.textContent; // faster than searchRange.toString()
|
||||||
|
|
||||||
href = elem.getAttribute("href");
|
href = elem.getAttribute("href");
|
||||||
for (var j = 0; j < text.length - 1; j++)
|
for (var j = 0; j < text.length - 1; j++)
|
||||||
{
|
{
|
||||||
@@ -782,9 +793,11 @@ outer:
|
|||||||
if (/[^a-z0-9]/.test(lowertext)) // 2x as fast as lowertext[0] > "a" etc. testing
|
if (/[^a-z0-9]/.test(lowertext)) // 2x as fast as lowertext[0] > "a" etc. testing
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (typeof(takenHints[lowertext]) === "undefined" ||
|
//dump(elem.tagname + " - " + text + ": " + word + "\n");
|
||||||
(href && takenHints[lowertext] == href))
|
|
||||||
{ // hint not yet taken or taken and href the same
|
// hint not yet taken or taken and href the same
|
||||||
|
if (typeof(takenHints[lowertext]) === "undefined" || (href && takenHints[lowertext] == href))
|
||||||
|
{
|
||||||
takenHints[lowertext] = href;
|
takenHints[lowertext] = href;
|
||||||
inl++;
|
inl++;
|
||||||
|
|
||||||
@@ -805,14 +818,27 @@ outer:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if we came here, there was no suitable inline hint, need
|
// if we came here, there was no suitable inline hint, need
|
||||||
// to create an absolutely positioned div
|
// to create an span relatively positioned to the element
|
||||||
var lower = elem.tagName.toLowerCase();
|
if (tagname != "input" && tagname != "textarea" && tagname != "select")
|
||||||
if (lower != "input" && lower != "textarea" && lower != "select")
|
|
||||||
{
|
{
|
||||||
|
// heuristics to avoid duplicate relative hints for the same things:
|
||||||
|
// 1. a link with the same href in one of the next two elements
|
||||||
|
// this often is true for images which have a textlink right to it
|
||||||
|
// or a menu made up of a <td>
|
||||||
|
if (i < res.snapshotLength-2)
|
||||||
|
{
|
||||||
|
if (href && href == res.snapshotItem(i+1).getAttribute("href") ||
|
||||||
|
href == res.snapshotItem(i+2).getAttribute("href"))
|
||||||
|
{
|
||||||
|
disc++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
elem.style.position = "relative";
|
elem.style.position = "relative";
|
||||||
rel++;
|
rel++;
|
||||||
var span = doc.createElement("span");
|
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");
|
span.setAttribute("style", "z-index: 5000; color:black; font-weight: bold; font-size: 10px; background-color:yellow; line-height: 10px; border: 0px; padding: 0px 1px 0px 0px; position: absolute; left: 0px; top: 0px");
|
||||||
var hint = getNextHintText(href);
|
var hint = getNextHintText(href);
|
||||||
if (!hint)
|
if (!hint)
|
||||||
return false;
|
return false;
|
||||||
@@ -821,7 +847,7 @@ outer:
|
|||||||
elem.appendChild(span);
|
elem.appendChild(span);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else // absolute positioning
|
||||||
{
|
{
|
||||||
var rect = elem.getClientRects()[0];
|
var rect = elem.getClientRects()[0];
|
||||||
if (rect)
|
if (rect)
|
||||||
@@ -838,8 +864,7 @@ outer:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vimperator.log("Done hinting " + res.snapshotLength + " items on " + doc.title);
|
vimperator.log("Hinted " + res.snapshotLength + " items on " + doc.title + " - inl: " + inl+ " rel: " + rel + " abs: " + abs + " discard: " + disc, 7);
|
||||||
vimperator.log("REL: " + rel + " - ABS: " + abs + " - INL: " + inl);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user