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

Add hints.addMode (e.g., hints.addMode("k", "Kill image", function (elem) elem.style.display="none", function () "//img")). Etc.

This commit is contained in:
Kris Maglione
2008-11-18 20:10:24 +00:00
parent 870538e032
commit a4072000c9
2 changed files with 78 additions and 84 deletions

View File

@@ -179,14 +179,19 @@ function Commands() //{{{
return NaN;
}
function quote(q, list) list.reduce(function (acc, [k, v]) {
v = "\\" + (v || k);
return function (str) acc(String.replace(str, k, v, "g"))
}, function (val) q + val + q);
const quoteMap = {
"\n": "n",
"\t": "t"
}
function quote(q, list)
{
let re = RegExp("[" + list + "]", "g");
return function (str) q + str.replace(re, function ($0, $1) $1 in quoteMap ? quoteMap[$1] : "\\" + $1) + q;
}
const quoteArg = {
'"': quote('"', [["\n", "n"], ["\t", "t"], ['"'], ["\\"]]),
"'": quote("'", [["\\"], ["'"]]),
"": quote("", [["\\"], [" "]])
'"': quote('"', '\n\t"\\\\'),
"'": quote("'", "\\\\'"),
"": quote("", "\\\\ ")
}
const ArgType = new Struct("description", "parse");
@@ -439,6 +444,9 @@ function Commands() //{{{
while (i < str.length)
{
// skip whitespace
//let re = /^\s*/;
//re.lastIndex = i;
//i += re.exec(str)[0].length;
if (/\s/.test(str[i]))
{
i++;
@@ -501,17 +509,17 @@ function Commands() //{{{
if (quote)
{
if (!complete)
if (complete)
{
args.completions = opt[3] || [];
if (typeof args.completions == "function")
args.completions = args.completions();
args.quote = quoteArg[sub[optname.length + 1]] || quoteArg[""];
return args;
}
liberator.echoerr("Invalid argument for option " + optname);
return null;
}
let compl = opt[3] || [];
if (typeof compl == "function")
compl = compl();
let quote = quoteArg[sub[optname.length + 1]] || quoteArg[""];
return [i + optname.length + 1, completion.filter(compl.map(quote), quote(arg))];
}
if (!invalid)
{

View File

@@ -32,6 +32,8 @@ function Hints() //{{{
////////////////////// PRIVATE SECTION /////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
const ELEM = 0, TEXT = 1, SPAN = 2, IMGSPAN = 3, BGCOLOR = 4, COLOR = 5;
var myModes = config.browserModes;
var hintMode;
@@ -53,24 +55,26 @@ function Hints() //{{{
// docs = { doc: document, start: start_index in hints[], end: end_index in hints[] }
var docs = [];
const Mode = new Struct("prompt", "action", "extended");
const Mode = new Struct("prompt", "action", "tags");
Mode.defaultValue("tags", function () function () options.hinttags);
function extended() options.extendedhinttags;
const hintModes = {
";": Mode("Focus hint", function (elem) buffer.focusElement(elem), true),
";": Mode("Focus hint", function (elem) buffer.focusElement(elem), extended),
a: Mode("Save hint with prompt", function (elem) buffer.saveLink(elem, false)),
s: Mode("Save hint", function (elem) buffer.saveLink(elem, true)),
o: Mode("Follow hint", function (elem) buffer.followLink(elem, liberator.CURRENT_TAB)),
t: Mode("Follow hint in a new tab", function (elem) buffer.followLink(elem, liberator.NEW_TAB)),
b: Mode("Follow hint in a background tab", function (elem) buffer.followLink(elem, liberator.NEW_BACKGROUND_TAB)),
v: Mode("View hint source", function (elem, loc) buffer.viewSource(loc, false), true),
V: Mode("View hint source", function (elem, loc) buffer.viewSource(loc, true), true),
w: Mode("Follow hint in a new window", function (elem) buffer.followLink(elem, liberator.NEW_WINDOW), true),
v: Mode("View hint source", function (elem, loc) buffer.viewSource(loc, false), extended),
V: Mode("View hint source", function (elem, loc) buffer.viewSource(loc, true), extended),
w: Mode("Follow hint in a new window", function (elem) buffer.followLink(elem, liberator.NEW_WINDOW), extended),
"?": Mode("Show information for hint", function (elem) buffer.showElementInfo(elem), true),
"?": Mode("Show information for hint", function (elem) buffer.showElementInfo(elem), extended),
O: Mode("Open location based on hint", function (elem, loc) commandline.open(":", "open " + loc, modes.EX)),
T: Mode("Open new tab based on hint", function (elem, loc) commandline.open(":", "tabopen " + loc, modes.EX)),
W: Mode("Open new window based on hint", function (elem, loc) commandline.open(":", "winopen " + loc, modes.EX)),
y: Mode("Yank hint location", function (elem, loc) util.copyToClipboard(loc, true)),
Y: Mode("Yank hint description", function (elem) util.copyToClipboard(elem.textContent || "", true), true),
Y: Mode("Yank hint description", function (elem) util.copyToClipboard(elem.textContent || "", true), extended),
};
// reset all important variables
@@ -112,7 +116,7 @@ function Hints() //{{{
<span class="liberator-hint"/>, doc);
var elem, tagname, text, span, rect;
var res = buffer.evaluateXPath(options[hintMode.extended ? "extendedhinttags" : "hinttags"], doc, null, true);
var res = buffer.evaluateXPath(hintMode.tags(), doc, null, true);
var fragment = doc.createDocumentFragment();
var start = pageHints.length;
@@ -181,19 +185,16 @@ function Hints() //{{{
var activelinkfgcolor = options["activelinkfgcolor"];
var activelinkbgcolor = options["activelinkbgcolor"];
var elem, tagname, text, rect, span, imgspan;
var hintnum = 1;
var validHint = hintMatcher(hintString.toLowerCase());
var activeHint = hintNumber || 1;
let elem, tagname, text, rect, span, imgspan;
let hintnum = 1;
let validHint = hintMatcher(hintString.toLowerCase());
let activeHint = hintNumber || 1;
validHints = [];
for (let j = 0; j < docs.length; j++)
for (let [,{ doc: doc, start: start, end: end }] in Iterator(docs))
{
var doc = docs[j].doc;
var start = docs[j].start;
var end = docs[j].end;
var scrollX = doc.defaultView.scrollX;
var scrollY = doc.defaultView.scrollY;
let scrollX = doc.defaultView.scrollX;
let scrollY = doc.defaultView.scrollY;
inner:
for (let i in (util.interruptableRange(start, end + 1, 500)))
@@ -208,8 +209,8 @@ function Hints() //{{{
imgspan.style.display = "none";
// reset background color
elem.style.backgroundColor = hint[4];
elem.style.color = hint[5];
elem.style.backgroundColor = hint[BGCOLOR];
elem.style.color = hint[COLOR];
continue inner;
}
@@ -230,7 +231,7 @@ function Hints() //{{{
imgspan.style.width = (rect.right - rect.left) + "px";
imgspan.style.height = (rect.bottom - rect.top) + "px";
imgspan.className = "liberator-hint";
hint[3] = imgspan;
hint[IMGSPAN] = imgspan;
doc.body.appendChild(imgspan);
}
imgspan.style.backgroundColor = (activeHint == hintnum) ? activelinkbgcolor : linkbgcolor;
@@ -240,7 +241,7 @@ function Hints() //{{{
if (!imgspan)
elem.style.backgroundColor = (activeHint == hintnum) ? activelinkbgcolor : linkbgcolor;
elem.style.color = (activeHint == hintnum) ? activelinkfgcolor : linkfgcolor;
span.textContent = "" + (hintnum++);
span.textContent = String(hintnum++);
span.style.display = "inline";
validHints.push(elem);
}
@@ -255,32 +256,27 @@ function Hints() //{{{
var firstElemBgColor = "";
var firstElemColor = "";
for (let j = 0; j < docs.length; j++)
for (let [,{ doc: doc, start: start, end: end }] in Iterator(docs))
{
var doc = docs[j].doc;
var start = docs[j].start;
var end = docs[j].end;
for (let i = start; i <= end; i++)
for (let i in util.range(start, end + 1))
{
let hint = pageHints[i];
// remove the span for the numeric display part
doc.body.removeChild(hint[2]);
if (hint[3]) // a transparent span for images
doc.body.removeChild(hint[3]);
doc.body.removeChild(hint[SPAN]);
if (hint[IMGSPAN]) // a transparent span for images
doc.body.removeChild(hint[IMGSPAN]);
if (timeout && firstElem == hint[0])
if (timeout && firstElem == hint[ELEM])
{
firstElemBgColor = hint[4];
firstElemColor = hint[5];
firstElemBgColor = hint[BGCOLOR];
firstElemColor = hint[COLOR];
}
else
{
// restore colors
var elem = hint[0];
elem.style.backgroundColor = hint[4];
elem.style.color = hint[5];
}
var elem = hint[ELEM];
elem.style.backgroundColor = hint[BGCOLOR];
elem.style.color = hint[COLOR]; }
}
// animate the disappearance of the first hint
@@ -381,19 +377,7 @@ function Hints() //{{{
function containsMatcher(hintString) //{{{
{
var tokens = hintString.split(/ +/);
function contains(textOfLink)
{
for (let i = 0; i < tokens.length; i++)
{
if (textOfLink.indexOf(tokens[i]) < 0)
return false;
}
return true;
}
return contains;
return function (linkText) tokens.every(function (token) linkText.indexOf(token) >= 0);
} //}}}
function wordStartsWithMatcher(hintString, allowWordOverleaping) //{{{
@@ -401,23 +385,23 @@ function Hints() //{{{
var hintStrings = hintString.split(/ +/);
var wordSplitRegex = new RegExp(options["wordseparators"]);
// What the **** does this do? --Kris
function charsAtBeginningOfWords(chars, words, allowWordOverleaping)
{
var charIdx = 0;
var numMatchedWords = 0;
for (let wIdx = 0; wIdx < words.length; wIdx++)
for (let [,word] in Iterator(words))
{
var word = words[wIdx];
if (word.length == 0)
continue;
var wcIdx = 0;
let wcIdx = 0;
// Check if the current word matches same characters as the previous word.
// Each already matched word has matched at least one character.
if (charIdx > numMatchedWords)
{
var matchingStarted = false;
for (let i = numMatchedWords; i < charIdx; i++)
let matchingStarted = false;
for (let i in util.range(numMatchedWords, charIdx))
{
if (chars[i] == word[wcIdx])
{
@@ -433,9 +417,10 @@ function Hints() //{{{
}
// the current word matches same characters as the previous word
var prevCharIdx;
if (wcIdx > 0)
{
var prevCharIdx = charIdx;
prevCharIdx = charIdx;
// now check if it matches additional characters
for (; wcIdx < word.length && charIdx < chars.length; wcIdx++, charIdx++)
{
@@ -461,7 +446,7 @@ function Hints() //{{{
// try to match the next characters
else
{
var prevCharIdx = charIdx;
prevCharIdx = charIdx;
for (let i = 0; i < word.length && charIdx < chars.length; i++, charIdx++)
{
if (word[i] != chars[charIdx])
@@ -487,16 +472,13 @@ function Hints() //{{{
function stringsAtBeginningOfWords(strings, words, allowWordOverleaping)
{
var strIdx = 0;
for (let wIdx = 0; wIdx < words.length; wIdx++)
for (let [,word] in Iterator(words))
{
var word = words[wIdx];
if (word.length == 0)
continue;
var str = strings[strIdx];
if (str.length == 0)
strIdx++;
else if (word.indexOf(str) == 0)
let str = strings[strIdx];
if (str.length == 0 || word.indexOf(str) == 0)
strIdx++;
else if (!allowWordOverleaping)
return false;
@@ -510,16 +492,15 @@ function Hints() //{{{
if (strings[strIdx].length != 0)
return false;
}
return (strIdx == strings.length);
return true;
}
function wordStartsWith(textOfLink)
function wordStartsWith(linkText)
{
if (hintStrings.length == 1 && hintStrings[0].length == 0)
return true;
var words = textOfLink.split(wordSplitRegex);
let words = linkText.split(wordSplitRegex);
if (hintStrings.length == 1)
return charsAtBeginningOfWords(hintStrings[0], words, allowWordOverleaping);
else
@@ -592,7 +573,7 @@ function Hints() //{{{
options.add(["wordseparators", "wsp"],
"How words are split for hintmatching",
"string", '[\\.,!\\?:;/\\\"\\^\\$%&?\\(\\)\\[\\]\\{\\}<>#\\*\\+\\|=~ _\\-]');
"string", '[.,!?:;/"^$%&?()[\\]{}<>#*+|=~ _-]');
/////////////////////////////////////////////////////////////////////////////}}}
////////////////////// MAPPINGS ////////////////////////////////////////////////
@@ -617,6 +598,11 @@ function Hints() //{{{
return {
addMode: function (mode)
{
hintModes[mode] = Mode.apply(Mode, Array.slice(arguments, 1));
},
show: function (minor, filter, win)
{
hintMode = hintModes[minor];