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:
@@ -179,14 +179,19 @@ function Commands() //{{{
|
|||||||
return NaN;
|
return NaN;
|
||||||
}
|
}
|
||||||
|
|
||||||
function quote(q, list) list.reduce(function (acc, [k, v]) {
|
const quoteMap = {
|
||||||
v = "\\" + (v || k);
|
"\n": "n",
|
||||||
return function (str) acc(String.replace(str, k, v, "g"))
|
"\t": "t"
|
||||||
}, function (val) q + val + q);
|
}
|
||||||
|
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 = {
|
const quoteArg = {
|
||||||
'"': quote('"', [["\n", "n"], ["\t", "t"], ['"'], ["\\"]]),
|
'"': quote('"', '\n\t"\\\\'),
|
||||||
"'": quote("'", [["\\"], ["'"]]),
|
"'": quote("'", "\\\\'"),
|
||||||
"": quote("", [["\\"], [" "]])
|
"": quote("", "\\\\ ")
|
||||||
}
|
}
|
||||||
|
|
||||||
const ArgType = new Struct("description", "parse");
|
const ArgType = new Struct("description", "parse");
|
||||||
@@ -439,6 +444,9 @@ function Commands() //{{{
|
|||||||
while (i < str.length)
|
while (i < str.length)
|
||||||
{
|
{
|
||||||
// skip whitespace
|
// skip whitespace
|
||||||
|
//let re = /^\s*/;
|
||||||
|
//re.lastIndex = i;
|
||||||
|
//i += re.exec(str)[0].length;
|
||||||
if (/\s/.test(str[i]))
|
if (/\s/.test(str[i]))
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
@@ -501,16 +509,16 @@ function Commands() //{{{
|
|||||||
|
|
||||||
if (quote)
|
if (quote)
|
||||||
{
|
{
|
||||||
if (!complete)
|
if (complete)
|
||||||
{
|
{
|
||||||
liberator.echoerr("Invalid argument for option " + optname);
|
args.completions = opt[3] || [];
|
||||||
return null;
|
if (typeof args.completions == "function")
|
||||||
|
args.completions = args.completions();
|
||||||
|
args.quote = quoteArg[sub[optname.length + 1]] || quoteArg[""];
|
||||||
|
return args;
|
||||||
}
|
}
|
||||||
let compl = opt[3] || [];
|
liberator.echoerr("Invalid argument for option " + optname);
|
||||||
if (typeof compl == "function")
|
return null;
|
||||||
compl = compl();
|
|
||||||
let quote = quoteArg[sub[optname.length + 1]] || quoteArg[""];
|
|
||||||
return [i + optname.length + 1, completion.filter(compl.map(quote), quote(arg))];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!invalid)
|
if (!invalid)
|
||||||
|
|||||||
124
content/hints.js
124
content/hints.js
@@ -32,6 +32,8 @@ function Hints() //{{{
|
|||||||
////////////////////// PRIVATE SECTION /////////////////////////////////////////
|
////////////////////// PRIVATE SECTION /////////////////////////////////////////
|
||||||
/////////////////////////////////////////////////////////////////////////////{{{
|
/////////////////////////////////////////////////////////////////////////////{{{
|
||||||
|
|
||||||
|
const ELEM = 0, TEXT = 1, SPAN = 2, IMGSPAN = 3, BGCOLOR = 4, COLOR = 5;
|
||||||
|
|
||||||
var myModes = config.browserModes;
|
var myModes = config.browserModes;
|
||||||
|
|
||||||
var hintMode;
|
var hintMode;
|
||||||
@@ -53,24 +55,26 @@ function Hints() //{{{
|
|||||||
// docs = { doc: document, start: start_index in hints[], end: end_index in hints[] }
|
// docs = { doc: document, start: start_index in hints[], end: end_index in hints[] }
|
||||||
var docs = [];
|
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 = {
|
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)),
|
a: Mode("Save hint with prompt", function (elem) buffer.saveLink(elem, false)),
|
||||||
s: Mode("Save hint", function (elem) buffer.saveLink(elem, true)),
|
s: Mode("Save hint", function (elem) buffer.saveLink(elem, true)),
|
||||||
o: Mode("Follow hint", function (elem) buffer.followLink(elem, liberator.CURRENT_TAB)),
|
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)),
|
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)),
|
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, false), extended),
|
||||||
V: Mode("View hint source", function (elem, loc) buffer.viewSource(loc, true), true),
|
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), true),
|
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)),
|
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)),
|
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)),
|
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 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
|
// reset all important variables
|
||||||
@@ -112,7 +116,7 @@ function Hints() //{{{
|
|||||||
<span class="liberator-hint"/>, doc);
|
<span class="liberator-hint"/>, doc);
|
||||||
|
|
||||||
var elem, tagname, text, span, rect;
|
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 fragment = doc.createDocumentFragment();
|
||||||
var start = pageHints.length;
|
var start = pageHints.length;
|
||||||
@@ -181,19 +185,16 @@ function Hints() //{{{
|
|||||||
var activelinkfgcolor = options["activelinkfgcolor"];
|
var activelinkfgcolor = options["activelinkfgcolor"];
|
||||||
var activelinkbgcolor = options["activelinkbgcolor"];
|
var activelinkbgcolor = options["activelinkbgcolor"];
|
||||||
|
|
||||||
var elem, tagname, text, rect, span, imgspan;
|
let elem, tagname, text, rect, span, imgspan;
|
||||||
var hintnum = 1;
|
let hintnum = 1;
|
||||||
var validHint = hintMatcher(hintString.toLowerCase());
|
let validHint = hintMatcher(hintString.toLowerCase());
|
||||||
var activeHint = hintNumber || 1;
|
let activeHint = hintNumber || 1;
|
||||||
validHints = [];
|
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;
|
let scrollX = doc.defaultView.scrollX;
|
||||||
var start = docs[j].start;
|
let scrollY = doc.defaultView.scrollY;
|
||||||
var end = docs[j].end;
|
|
||||||
var scrollX = doc.defaultView.scrollX;
|
|
||||||
var scrollY = doc.defaultView.scrollY;
|
|
||||||
|
|
||||||
inner:
|
inner:
|
||||||
for (let i in (util.interruptableRange(start, end + 1, 500)))
|
for (let i in (util.interruptableRange(start, end + 1, 500)))
|
||||||
@@ -208,8 +209,8 @@ function Hints() //{{{
|
|||||||
imgspan.style.display = "none";
|
imgspan.style.display = "none";
|
||||||
|
|
||||||
// reset background color
|
// reset background color
|
||||||
elem.style.backgroundColor = hint[4];
|
elem.style.backgroundColor = hint[BGCOLOR];
|
||||||
elem.style.color = hint[5];
|
elem.style.color = hint[COLOR];
|
||||||
continue inner;
|
continue inner;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,7 +231,7 @@ function Hints() //{{{
|
|||||||
imgspan.style.width = (rect.right - rect.left) + "px";
|
imgspan.style.width = (rect.right - rect.left) + "px";
|
||||||
imgspan.style.height = (rect.bottom - rect.top) + "px";
|
imgspan.style.height = (rect.bottom - rect.top) + "px";
|
||||||
imgspan.className = "liberator-hint";
|
imgspan.className = "liberator-hint";
|
||||||
hint[3] = imgspan;
|
hint[IMGSPAN] = imgspan;
|
||||||
doc.body.appendChild(imgspan);
|
doc.body.appendChild(imgspan);
|
||||||
}
|
}
|
||||||
imgspan.style.backgroundColor = (activeHint == hintnum) ? activelinkbgcolor : linkbgcolor;
|
imgspan.style.backgroundColor = (activeHint == hintnum) ? activelinkbgcolor : linkbgcolor;
|
||||||
@@ -240,7 +241,7 @@ function Hints() //{{{
|
|||||||
if (!imgspan)
|
if (!imgspan)
|
||||||
elem.style.backgroundColor = (activeHint == hintnum) ? activelinkbgcolor : linkbgcolor;
|
elem.style.backgroundColor = (activeHint == hintnum) ? activelinkbgcolor : linkbgcolor;
|
||||||
elem.style.color = (activeHint == hintnum) ? activelinkfgcolor : linkfgcolor;
|
elem.style.color = (activeHint == hintnum) ? activelinkfgcolor : linkfgcolor;
|
||||||
span.textContent = "" + (hintnum++);
|
span.textContent = String(hintnum++);
|
||||||
span.style.display = "inline";
|
span.style.display = "inline";
|
||||||
validHints.push(elem);
|
validHints.push(elem);
|
||||||
}
|
}
|
||||||
@@ -255,32 +256,27 @@ function Hints() //{{{
|
|||||||
var firstElemBgColor = "";
|
var firstElemBgColor = "";
|
||||||
var firstElemColor = "";
|
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;
|
for (let i in util.range(start, end + 1))
|
||||||
var start = docs[j].start;
|
|
||||||
var end = docs[j].end;
|
|
||||||
|
|
||||||
for (let i = start; i <= end; i++)
|
|
||||||
{
|
{
|
||||||
let hint = pageHints[i];
|
let hint = pageHints[i];
|
||||||
// remove the span for the numeric display part
|
// remove the span for the numeric display part
|
||||||
doc.body.removeChild(hint[2]);
|
doc.body.removeChild(hint[SPAN]);
|
||||||
if (hint[3]) // a transparent span for images
|
if (hint[IMGSPAN]) // a transparent span for images
|
||||||
doc.body.removeChild(hint[3]);
|
doc.body.removeChild(hint[IMGSPAN]);
|
||||||
|
|
||||||
if (timeout && firstElem == hint[0])
|
if (timeout && firstElem == hint[ELEM])
|
||||||
{
|
{
|
||||||
firstElemBgColor = hint[4];
|
firstElemBgColor = hint[BGCOLOR];
|
||||||
firstElemColor = hint[5];
|
firstElemColor = hint[COLOR];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// restore colors
|
// restore colors
|
||||||
var elem = hint[0];
|
var elem = hint[ELEM];
|
||||||
elem.style.backgroundColor = hint[4];
|
elem.style.backgroundColor = hint[BGCOLOR];
|
||||||
elem.style.color = hint[5];
|
elem.style.color = hint[COLOR]; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// animate the disappearance of the first hint
|
// animate the disappearance of the first hint
|
||||||
@@ -381,19 +377,7 @@ function Hints() //{{{
|
|||||||
function containsMatcher(hintString) //{{{
|
function containsMatcher(hintString) //{{{
|
||||||
{
|
{
|
||||||
var tokens = hintString.split(/ +/);
|
var tokens = hintString.split(/ +/);
|
||||||
|
return function (linkText) tokens.every(function (token) linkText.indexOf(token) >= 0);
|
||||||
function contains(textOfLink)
|
|
||||||
{
|
|
||||||
for (let i = 0; i < tokens.length; i++)
|
|
||||||
{
|
|
||||||
if (textOfLink.indexOf(tokens[i]) < 0)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return contains;
|
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
function wordStartsWithMatcher(hintString, allowWordOverleaping) //{{{
|
function wordStartsWithMatcher(hintString, allowWordOverleaping) //{{{
|
||||||
@@ -401,23 +385,23 @@ function Hints() //{{{
|
|||||||
var hintStrings = hintString.split(/ +/);
|
var hintStrings = hintString.split(/ +/);
|
||||||
var wordSplitRegex = new RegExp(options["wordseparators"]);
|
var wordSplitRegex = new RegExp(options["wordseparators"]);
|
||||||
|
|
||||||
|
// What the **** does this do? --Kris
|
||||||
function charsAtBeginningOfWords(chars, words, allowWordOverleaping)
|
function charsAtBeginningOfWords(chars, words, allowWordOverleaping)
|
||||||
{
|
{
|
||||||
var charIdx = 0;
|
var charIdx = 0;
|
||||||
var numMatchedWords = 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)
|
if (word.length == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var wcIdx = 0;
|
let wcIdx = 0;
|
||||||
// Check if the current word matches same characters as the previous word.
|
// Check if the current word matches same characters as the previous word.
|
||||||
// Each already matched word has matched at least one character.
|
// Each already matched word has matched at least one character.
|
||||||
if (charIdx > numMatchedWords)
|
if (charIdx > numMatchedWords)
|
||||||
{
|
{
|
||||||
var matchingStarted = false;
|
let matchingStarted = false;
|
||||||
for (let i = numMatchedWords; i < charIdx; i++)
|
for (let i in util.range(numMatchedWords, charIdx))
|
||||||
{
|
{
|
||||||
if (chars[i] == word[wcIdx])
|
if (chars[i] == word[wcIdx])
|
||||||
{
|
{
|
||||||
@@ -433,9 +417,10 @@ function Hints() //{{{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// the current word matches same characters as the previous word
|
// the current word matches same characters as the previous word
|
||||||
|
var prevCharIdx;
|
||||||
if (wcIdx > 0)
|
if (wcIdx > 0)
|
||||||
{
|
{
|
||||||
var prevCharIdx = charIdx;
|
prevCharIdx = charIdx;
|
||||||
// now check if it matches additional characters
|
// now check if it matches additional characters
|
||||||
for (; wcIdx < word.length && charIdx < chars.length; wcIdx++, charIdx++)
|
for (; wcIdx < word.length && charIdx < chars.length; wcIdx++, charIdx++)
|
||||||
{
|
{
|
||||||
@@ -461,7 +446,7 @@ function Hints() //{{{
|
|||||||
// try to match the next characters
|
// try to match the next characters
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var prevCharIdx = charIdx;
|
prevCharIdx = charIdx;
|
||||||
for (let i = 0; i < word.length && charIdx < chars.length; i++, charIdx++)
|
for (let i = 0; i < word.length && charIdx < chars.length; i++, charIdx++)
|
||||||
{
|
{
|
||||||
if (word[i] != chars[charIdx])
|
if (word[i] != chars[charIdx])
|
||||||
@@ -487,16 +472,13 @@ function Hints() //{{{
|
|||||||
function stringsAtBeginningOfWords(strings, words, allowWordOverleaping)
|
function stringsAtBeginningOfWords(strings, words, allowWordOverleaping)
|
||||||
{
|
{
|
||||||
var strIdx = 0;
|
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)
|
if (word.length == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var str = strings[strIdx];
|
let str = strings[strIdx];
|
||||||
if (str.length == 0)
|
if (str.length == 0 || word.indexOf(str) == 0)
|
||||||
strIdx++;
|
|
||||||
else if (word.indexOf(str) == 0)
|
|
||||||
strIdx++;
|
strIdx++;
|
||||||
else if (!allowWordOverleaping)
|
else if (!allowWordOverleaping)
|
||||||
return false;
|
return false;
|
||||||
@@ -510,16 +492,15 @@ function Hints() //{{{
|
|||||||
if (strings[strIdx].length != 0)
|
if (strings[strIdx].length != 0)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
return (strIdx == strings.length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function wordStartsWith(textOfLink)
|
function wordStartsWith(linkText)
|
||||||
{
|
{
|
||||||
if (hintStrings.length == 1 && hintStrings[0].length == 0)
|
if (hintStrings.length == 1 && hintStrings[0].length == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
var words = textOfLink.split(wordSplitRegex);
|
let words = linkText.split(wordSplitRegex);
|
||||||
if (hintStrings.length == 1)
|
if (hintStrings.length == 1)
|
||||||
return charsAtBeginningOfWords(hintStrings[0], words, allowWordOverleaping);
|
return charsAtBeginningOfWords(hintStrings[0], words, allowWordOverleaping);
|
||||||
else
|
else
|
||||||
@@ -592,7 +573,7 @@ function Hints() //{{{
|
|||||||
|
|
||||||
options.add(["wordseparators", "wsp"],
|
options.add(["wordseparators", "wsp"],
|
||||||
"How words are split for hintmatching",
|
"How words are split for hintmatching",
|
||||||
"string", '[\\.,!\\?:;/\\\"\\^\\$%&?\\(\\)\\[\\]\\{\\}<>#\\*\\+\\|=~ _\\-]');
|
"string", '[.,!?:;/"^$%&?()[\\]{}<>#*+|=~ _-]');
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////}}}
|
/////////////////////////////////////////////////////////////////////////////}}}
|
||||||
////////////////////// MAPPINGS ////////////////////////////////////////////////
|
////////////////////// MAPPINGS ////////////////////////////////////////////////
|
||||||
@@ -617,6 +598,11 @@ function Hints() //{{{
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
||||||
|
addMode: function (mode)
|
||||||
|
{
|
||||||
|
hintModes[mode] = Mode.apply(Mode, Array.slice(arguments, 1));
|
||||||
|
},
|
||||||
|
|
||||||
show: function (minor, filter, win)
|
show: function (minor, filter, win)
|
||||||
{
|
{
|
||||||
hintMode = hintModes[minor];
|
hintMode = hintModes[minor];
|
||||||
|
|||||||
Reference in New Issue
Block a user