YouTube AutoPager

YouTube用のAutoPager。多分どこかにあるんだろけど適当に作ってみた。
Firefox+GreasemonkeyOperaの両方で動くはず。
ちなみにscroll_remainが場合分けしているのは標準モードとかそのへんで document.body.scrollHeight あたりが変わるらしいから。最初気づかず、Firefoxで試したときにはまった。

// ==UserScript==
// @name YouTube AutoPager
// @include http://*.youtube.com/*
// ==/UserScript==

(function(){
    var base = "http://" + location.host;
    var nextPage;

    var appendPage = function(path, f) {
	var req;
	var url = base + path;
	try {
	    req = new ActiveXObject("Microsoft.XMLHTTP");
	} catch(e) {
	    req = new XMLHttpRequest();
	}
	req.onreadystatechange = function() {
	    if (req.readyState != 4) return;
	    var v = req.responseText;
	    var start = v.indexOf('<div id="mainContent">');
	    var end = v.indexOf('<div id="footerDiv">');

	    var div = v.substr(start, end - start);
	    div = div.replace(/^<[^>]+>/, "");
	    div = div.replace(/<\/div>\s+$/, "");

	    nextPage = getNextPage(div);
	    var content = document.getElementById("mainContent");
	    content.innerHTML += div;
	    window.status = "loading " + url + " done";
	    f();
	};
	req.open("GET", url, true);
	window.status = "loading " + url;
	req.send(null);
    };

    var getNextPage = function(html) {
	var lines = html.split("\n");
	var page = null;
	for (var i = lines.length - 1; i >= 0; i--) {
	    if (lines[i].match(/location\.href='(.*)'/)) {
		var page_tmp = RegExp.$1;
		if (lines[i].match(/Next/)) {
		    page = page_tmp;
		} else {
		    page = null;
		}
		break;
	    }
	}

	return page;
    }

    var do_request = function(f) {
	var lines = document.getElementById("mainContent").innerHTML.split("\n");
	if (nextPage) {
	    appendPage(nextPage, f);
	}
    };

    var scroll_remain;
    if (window.opera) {
	scroll_remain = function() {
	    var sc = document.body.scrollTop;
	    var total = document.body.scrollHeight - document.body.clientHeight;
	    return total - sc;
	}
    } else {
	scroll_remain = function() {
	    var sc = document.documentElement.scrollTop;
	    var total = document.documentElement.scrollHeight - document.documentElement.clientHeight;
	    return total - sc;
	}
    }

    var watch_scroll = function() {
	var self = arguments.callee;
	var next = function() { setTimeout(self, 200); };
	var remain = scroll_remain();

	if (remain < 1000) {
	    do_request(next);
	} else if (nextPage) {
	    next();
	}
    };

    var mainContent = document.getElementById("mainContent").innerHTML;
    nextPage = getNextPage(mainContent);

    watch_scroll();
})();