﻿// ==UserScript==
// @name            anchor list
// @description     ver 0.71 2006.09.15
// @namespace       http://f56.aaa.livedoor.jp/~tdnr/ppblog/
// @include         *

// const
var list_font = "normal normal bold 10px 'ＭＳ Ｐゴシック',Osaka,sans-serif";
var list_color = "Black";
var list_bgcolor = "Whitesmoke";
var list_opacity = 0.5;
var list_id = "a________list";
var list_small_scroll = 10;
var list_big_scroll = 30;

var select_anchor_bgcolor = "red";

// global
var selectAnchor = null;

// window keydown
window.addEventListener("keydown", function(e) 
{
	if (e.ctrlKey && e.keyCode == 122) {	// ctrl + F11
		if (document.links.length == 0) {
			return;
		}
		e.preventDefault();
		callList();
	}
}, false);

function callList()
{
	var list = document.getElementById(list_id);
	if(list == undefined) {
		list = makeList(list_id);
		document.body.appendChild(list);

		list.selectedIndex = 0;
//		list.options[0].selected = true;
		changeList(list, null);
	}

	visibleList(list);
}

function makeList(id)
{
	var list = buildSelectList(id);

	var len = document.links.length;
	var col = String(len).length;
	var zero = "";
	for(var i=0; i<col; i++) {
		zero += "0";
	}

	for(var i=0; i<len; i++) {
		var start = String(i).length;
		var head = zero + String(i);
		head = head.substring(start);

		var text = "[no text]";
		if (document.links[i].text != undefined) {
			text = document.links[i].text;
		}

		var option = makeOption(head + ":" + text, i);
		list.appendChild(option);
	}

	return list;
}

function buildSelectList(id)
{
	var list = document.createElement("select");
	list.id = id;
	list.size = 100;

	list.style.font = list_font;
	list.style.color = list_color;
	list.style.backgroundColor = list_bgcolor;
	list.style.opacity = list_opacity;
	list.style.zIndex = 10;
	list.style.visibility = "hidden";

	list.addEventListener("keydown", function(e) { keydownList(this, e); }, false);
	list.addEventListener("change", function(e) { changeList(this, e); }, false);

	return list;
}

function makeOption(label, value)
{
	var text = document.createTextNode(label);

	var element = document.createElement("option");
	element.value = value;
	element.selected = false;
	element.appendChild(text);

	return element;
}

function keydownList(list, e)
{
	var cmdFlg = true;

	// shift
	if (e.shiftKey) {
		switch(e.keyCode) {
			case 71:	// jump(shift+g)
				var index = prompt("Jump", "");
				if (index == null) {
					break;
				}

				if (index.match(/[^0-9]/g)) {
					break;
				}

				selectedList(list, index);
				break;
			default:
				cmdFlg = false;
				break;
		}

		if (cmdFlg) {
			e.preventDefault();
			return;
		}
	}

	// ctrl
	if (e.ctrlKey) {
		switch(e.keyCode) {
			case 66:	// big up(ctrl+b)
				var next = list.selectedIndex - list_big_scroll;
				selectedList(list, next);
				break;

			case 70:	// big down(ctrl+f)
				var next = list.selectedIndex + list_big_scroll;
				selectedList(list, next);
				break;

			case 85:	// small up(ctrl+u)
				var next = list.selectedIndex - list_small_scroll;
				selectedList(list, next);
				break;

			case 68:	// small down(ctrl+d)
				var next = list.selectedIndex + list_small_scroll;
				selectedList(list, next);
				break;

			default:
				cmdFlg = false;
				break;
		}

		if (cmdFlg) {
			e.preventDefault();
			return;
		}
	}

	// single
	switch(e.keyCode) {
		case 13:	// enter
			visibleList(list);
			selectAnchor.focus();
			break;

		case 74:	// down(j)
			var next = list.selectedIndex + 1;
			selectedList(list, next);
			break;

		case 75:	// up(k)
			var next = list.selectedIndex - 1;
			selectedList(list, next);
			break;

		default:
			cmdFlg = false;
			break;
	}

	if (cmdFlg) {
		e.preventDefault();
		return;
	}
}

function changeList(list, e)
{
	var index = list.selectedIndex;

	if (selectAnchor != null) {
		selectAnchor.style.backgroundColor = selectAnchor.before_bgcolor;
	}

	selectAnchor = document.links[index];

	selectAnchor.before_bgcolor = selectAnchor.style.backgroundColor;
	selectAnchor.style.backgroundColor = select_anchor_bgcolor;
}

function visibleList(list)
{
	if (list.style.visibility == "visible") {
		if (selectAnchor != null) {
			selectAnchor.focus();
		}
		list.style.visibility = "hidden";
	} else {
		moveList(list);
		list.style.visibility = "visible";
		list.focus();
	}
}

function moveList(list)
{
	var listWidth = Math.floor(window.innerWidth / 4);

	list.style.position = "absolute";

	list.style.height = window.innerHeight + "px";
	list.style.width = listWidth + "px";

	list.style.top = window.pageYOffset + "px";
	list.style.left = (window.innerWidth - listWidth + window.pageXOffset - 20) + "px";
}

function selectedList(list, index)
{
	index = Number(index);
	if (index < 0) {
		return;
	}
	if (index >= list.length) {
		return;
	}

	list.selectedIndex = index;
//	list.options[index].selected = true;
	changeList(list, null);

	selectAnchor.focus();

	moveList(list);
	list.focus();
}


