Skip to content

Instantly share code, notes, and snippets.

@teramako
Created January 19, 2015 13:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save teramako/c8b2029663911277dd15 to your computer and use it in GitHub Desktop.
Save teramako/c8b2029663911277dd15 to your computer and use it in GitHub Desktop.
Vimperator プラグイン。<Leader>/ でページ内検索した時にリストを作成して foundlist コマンドで該当箇所にジャンプする。
var wm = new WeakMap;
mappings.addUserMap([modes.NORMAL], ["<Leader>/"], "Search forward for a pattern", function () { openPrompt(modes.SEARCH_FORWARD); });
commands.addUserCommand(['foundlist', 'fl'], 'show found list',
function (args) {
var index = parseInt(args.literalArg, 10);
if (Number.isNaN(index))
return;
var win = gBrowser.contentWindow;
if (wm.has(win)) {
let list = wm.get(win);
win.scrollBy(0, list[index].y - win.scrollY);
}
}, {
literal: 0,
completer: function (context, args) {
var win = gBrowser.contentWindow;
if (!wm.has(win)) {
context.title = ["Found List", "not generated"];
return;
}
var list = wm.get(win);
context.title = ["Found List", finder._lastSearchString];
context.anchored = false;
context.compare = CompletionContext.Sort.number;
context.completions = list.map((item,i) => [i+":["+item.x+","+item.y+"]:"+ item.summary, ""]);
}
},
true);
function openPrompt (mode) {
finder._backwards = mode == modes.SEARCH_BACKWARD;
//commandline.open(this._backwards ? "Find backwards" : "Find", "", mode);
commandline.input(finder._backwards ? "Find backwards" : "Find", onSubmit, {
onChange: function() { if (options["incsearch"]) finder.find(commandline.command) }
});
}
function onSubmit (str, forcedBackward) {
finder.closure.onSubmit(str, forcedBackward);
find(str);
}
function find (aWord) {
var win = gBrowser.contentWindow;
var {scrollX, scrollY} = win;
var result = [];
for (let range of gBrowser.finder._findIterator(aWord, win)) {
let r = range.cloneRange();
let sContinue = true, eContinue = true;
while (sContinue || eContinue) {
if (sContinue) sContinue = extendStart(r);
if (eContinue) eContinue = extendEnd(r);
if (r.toString().length > 50)
break;
}
let rect = range.getBoundingClientRect();
result.push({
x: Math.floor(rect.x + scrollX),
y: Math.floor(rect.y + scrollY),
summary: r.toString(),
});
}
wm.set(win, result);
return result;
}
function extendRange (aRange) {
var sRetValue = extendStart(aRange);
}
function extendStart(aRange) {
var s = aRange.startContainer;
if (isTextNode(s)) {
aRange.setStartBefore(s.previousSibling || s);
} else {
var offset = aRange.startOffset;
if (offset > 0) {
aRange.setStart(s, offset - 1);
} else if (isBlockElement(s)) {
return false;
} else {
aRange.setStartBefore(s);
}
}
return true;
}
function extendEnd(aRange) {
var len = aRange.toString().length;
var e = aRange.endContainer;
if (isTextNode(e)) {
aRange.setEndAfter(e.nextSibling || e);
} else {
var offset = aRange.endOffset;
if (offset < e.childNodes.length) {
aRange.setEnd(e, offset + 1);
} else if (isBlockElement(e)) {
return false;
} else {
aRange.setEndAfter(e);
}
}
return true;
}
function isTextNode(aNode) {
switch (aNode.nodeType) {
case Node.TEXT_NODE:
case Node.COMMENT_NODE:
case Node.CDATA_SECTION_NODE:
return true;
}
return false;
}
function isBlockElement(aNode) {
if (aNode.nodeType !== Node.ELEMENT_NODE) return false;
switch (aNode.localName) {
case 'div':
case 'p':
case 'h1':
case 'h2':
case 'h3':
case 'h4':
case 'h5':
case 'h6':
case 'h7':
case 'td':
case 'th':
case 'tr':
case 'pre':
case 'table':
case 'caption':
case 'section':
case 'article':
case 'header':
case 'footer':
case "li":
case "ul":
case "ol":
case "dt":
case "dl":
case "dd":
return true;
}
return false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment