Skip to content

Instantly share code, notes, and snippets.

@teramako
Forked from anonymous/page-nav.js
Last active Dec 18, 2015
Embed
What would you like to do?
[Vimperator]ページ内の見出し的要素へジャンプする奴
"use strict";
/**
* :nav コマンドでテキトウに補完を使いましょう
* :nnoremap v :nav<Space> とかすると快適かも
*/
var selector = "h1, h2, h3, h4, main, [role=main], [role=navigation], [role=search]";
var cache = new WeakMap;
function getJumpList (force) {
var browser = gBrowser.selectedBrowser,
doc = browser.contentDocument,
win = browser.contentWindow;
if (!force && cache.has(win))
return cache.get(win);
var items = [];
var wX = win.scrollX,
wY = win.scrollY,
index = 1;
for (let elm of doc.querySelectorAll(selector)) {
let id = elm.getAttribute("id") || "",
role = elm.getAttribute("role") || "",
rect = elm.getBoundingClientRect();
let localName = elm.localName,
key = index + ":" + localName + ":",
desc = elm.textContent.substring(0, 50).replace(/\s+/g, " ");
if (id)
key += "#" + id + ":";
if (role)
key += "[" + role + "]:"
items.push({
id: id,
key: key + desc,
desc: localName + ": " + desc,
x: wX + rect.left,
y: wY + rect.top,
node: elm,
});
index++;
}
cache.set(win, items);
return items;
}
function jumpTo (item) {
var win = gBrowser.contentWindow;
if (item.id)
win.location.hash = "#" + item.id;
else
win.scrollTo(Math.min(item.x, win.scrollMaxX), Math.min(item.y, win.scrollMaxY));
item.node.focus();
flashNode(item.node);
cache.delete(win);
}
function flashNode (node) {
var count = 7,
originalOUtline = node.style.outline,
win = node.ownerDocument.defaultView;
var id = win.setInterval(function(){
if (count <= 0) {
win.clearInterval(id);
node.style.outline = originalOUtline;
return;
}
node.style.outline = count % 2 ?
"2px solid red":
"0 solid transparent";
--count;
}, 200);
}
commands.addUserCommand(["nav"], "page jump",
function (args) {
var list = getJumpList();
var arg = args.string;
var m = arg.match(/^(\d+):?/);
if (m) {
let index = parseInt(m[1], 10) - 1;
if (index in list) {
jumpTo(list[index]);
return;
}
}
var item = list.filter(function (item) {
return item.key.contains(arg);
})[0];
if (item)
jumpTo(item);
}, {
literal: 0,
completer: function (context) {
context.title = ["Page Jump List"];
context.compare = CompletionContext.Sort.unsorted;
context.anchored = false;
context.completions = [[item.key, item.desc] for (item of getJumpList(true))];
},
}, true);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment