/*
* @title darekagakaku endless scroll and pushstate
* @description darekagakaku nikki wo random ni autopagerize with scroll push^H^H^H^HreplaceState
* @include http://darekagakaku.herokuapp.com/*
* @license MIT License
*/
// http://darekagakaku.herokuapp.com/ wo endless summer-ize!!!
// via http://wayback.archive.org/web/20131110230206/http://userscripts.org/scripts/review/47998
var next = location.href;
var depth = 0;
var hold = [];
hold.push({
"url": next,
"depth": depth
})
var State = true;
var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
var BASE_REMAIN_HEIGHT = 50;
var loading = false;
var now = new Date();
var bottom = new Date("Feburary 17, 2012"); /* http://darekagakaku.herokuapp.com/v/2012-02-17 */
var last_element = get_next_elements(document).pop();
if (!last_element) {
return error();
}
var insert_point = last_element.nextSibling;
var insert_parent = last_element.parentNode;
next_page_load();
window.addEventListener('scroll', function () {
if (loading) return;
var remain = document.documentElement.scrollHeight - window.innerHeight - window.pageYOffset;
if (State && remain < BASE_REMAIN_HEIGHT) {
next_page_load();
}
}, false);
function next_page_load() {
loading = true;
next = go();
var x = new XMLHttpRequest();
x.onload = function () {
if (x.status <= 200 && x.status < 300) {
load(x);
} else {
error();
}
};
x.open('GET', next, true);
x.send(null);
}
function load(x) {
var html = x.responseText.replace(/<script(?:[ \t\r\n][^>]*)?>[\S\s]*?<\/script[ \t\r\n]*>|<\/?(?:i?frame|html|script|object)(?:[ \t\r\n][^<>]*)?>/gi, ' ');
var htmlDoc;
if (document.implementation.createHTMLDocument) {
htmlDoc = document.implementation.createHTMLDocument('hogehoge')
} else {
htmlDoc = document.cloneNode(false);
if (htmlDoc) {
htmlDoc.appendChild(htmlDoc.importNode(document.documentElement, false));
} else {
htmlDoc = document.implementation.createDocument(null, 'html', null);
}
}
var range = document.createRange();
range.selectNodeContents(document.documentElement);
htmlDoc.documentElement.appendChild(range.createContextualFragment(html));
//next = get_next(htmlDoc);
var docs = get_next_elements(htmlDoc);
if (!docs.length) {
return error();
}
var lastElement = get_next_elements(document).pop();
depth = getElementPosition(lastElement).bottom;
hold.push({
"url": next,
"depth": depth
})
docs = docs.map(function (doc) {
return insert_parent.insertBefore(document.importNode(doc, true), insert_point);
});
//history.pushState("", "", next);
loading = false;
// if (!next) {
// return terminate();
// }
}
var timer = null;
window.addEventListener('scroll', function () {
clearTimeout(timer);
timer = setTimeout(function () {
onscroll();
}, 10);
}, false);
function onscroll() {
current = window.pageYOffset;
for(var i = hold.length - 1, section; (ele = hold[i]); i--) {
if(ele.depth <= current) break;
}
ele = hold[i];
if (ele.url != location.href) {
//history.pushState("", "", ele.url);
history.replaceState("", "", ele.url);
console.log('current: '+current);
console.log('url: '+ele.url);
console.log('depth: '+ele.depth);
}
}
//function get_next(doc) {
// return doc.evaluate('id("next_page_link")', doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
//}
function get_next_elements(doc) {
var r = doc.evaluate('//div[@class="content"]', doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i = 0, l = r.snapshotLength, res = new Array(l); i < l; i++) res[i] = r.snapshotItem(i);
return res;
}
function error() {
return console.log('error');
State = false;
}
function terminate() {
return console.log('terminate');
State = false;
}
// via http://d.hatena.ne.jp/javascripter/20080531/1212264942
function getElementPosition(elem) {
var position = elem.getBoundingClientRect();
return {
left: Math.round(window.scrollX + position.left),
right: Math.round(window.scrollY + position.right),
top: Math.round(window.scrollY + position.top),
bottom: Math.round(window.scrollY + position.bottom)
}
}
// via http://let.hatelabo.jp/taizooo/let/gYC-xcG60rLuBA
function trim(num, l) {
if (num < 0) {
num = -(num);
}
if (typeof (num) != 'string') {
num = '' + num;
}
var s = l - num.length;
while (s > 0) {
num = '0' + num;
--s;
}
return num;
}
function rday(max, min) {
max = max.getTime();
min = min.getTime();
rd = new Date(Math.floor(Math.random() * (max - min) + min));
d = trim(rd.getFullYear(), 4) + "-" + trim(rd.getMonth() + 1, 2) + "-" + trim(rd.getDate(), 2);
return d;
}
function go() {
url = "http://darekagakaku.herokuapp.com/v/" + rday(now, bottom);
if (next == url) {
url = "http://darekagakaku.herokuapp.com/a";
}
return url;
}