/*
* @title endless summer on dsbd
* @description promotion version (Exponential Endless Summer)
* @include http://www.tumblr.com/dashboard*
* @include http://www.tumblr.com/show*
* @include http://www.tumblr.com/blog*
* @license reblog commons license ( cc by 3.0 )
* @javascript_url
*/
// bookmark
// autopager part from "twitter.AutoPager" : http://userscripts.org/scripts/review/47998
// random choice part from ReblogMachine : http://reblog.machine.mamemomonga.com/
// -> ReblogMachine.endless_summer#choice : http://reblog.machine.mamemomonga.com/js/ReblogMachine.js
// history.pushState/history.replaceState : http://d.hatena.ne.jp/javascripter/20100404/1270411268
// show page regexp from "Tumblr Dashboard Filter by Post Type" : http://userscripts.org/scripts/review/40794
// Exponential Endless Summer version 2014 by saitamanodoruji : http://tumblr.g.hatena.ne.jp/saitamanodoruji/20140831/1409496698
(function() {
var num = 2;
var start_url = location.href;
var oldest_id = 264102; // http://ku.tumblr.com/post/264102
var latest_id = get_latest_id(document);
var latest_id_n = 50000000000;
latest_id = (latest_id > latest_id_n) ? latest_id : latest_id_n;
console.log('latest_id: ' + latest_id);
var State = true;
var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
var BASE_REMAIN_HEIGHT = 10000;
var loading = false;
var loadingNotify = document.createElement('div');
loadingNotify.setAttribute('style', 'position: fixed; top:15px; left:15px;color:white;font-size:13px;background-color:#000;');
loadingNotify.id = 'endlessSummerLoading';
loadingNotify.innerText = 'loading...';
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;
/* Exponential Endless Summer 2014 */
var draw = function(oldestID, newestID) {
var oldestUTime = getUnixTimeFromPostID(oldestID);
var newestUTime = getUnixTimeFromPostID(newestID);
var drawnUTime = oldestUTime + Math.floor((newestUTime - oldestUTime) * Math.random());
return getPostIDFromUnixTime(drawnUTime);
};
var getPostIDFromUnixTime = function(utime) {
if (utime < 1149465600000) {
return;
} else if (utime === Number.POSITIVE_INFINITY) {
return Number.POSITIVE_INFINITY;
}
for (var i = 0; i < params.length; i++) {
if (utime <= params[i].upperBound) {
return Math.ceil(params[i].coefAlpha * Math.exp(params[i].coefBeta * (utime - 1136073600000)));
}
}
};
var getUnixTimeFromPostID = function(postID) {
if (postID < 1) {
return;
}
for (var i = 0; i < params.length; i++) {
if (postID <= getPostIDFromUnixTime(params[i].upperBound)) {
return Math.floor(Math.log(postID / params[i].coefAlpha) / params[i].coefBeta) + 1136073600000;
}
}
};
var params = [
// f_i(t) = Alpha_i * exp[Beta_i * (t - t_0)]
// t: Unix time [msec]
// t_0 = 1136073600000 [msec] (2006-01-01T00:00:00+09:00)
{
coefAlpha: 1.211 * Math.pow(10, -1),
coefBeta: 1.571 * Math.pow(10, -10),
upperBound: 1160012789359
}, {
coefAlpha: 3.619 * Math.pow(10, -13),
coefBeta: 1.266 * Math.pow(10, -9),
upperBound: 1163269541924
}, {
coefAlpha: 2.120 * Math.pow(10, 0),
coefBeta: 1.846 * Math.pow(10, -10),
upperBound: 1172120791893
}, {
coefAlpha: 1.179 * Math.pow(10, -49),
coefBeta: 3.331 * Math.pow(10, -9),
upperBound: 1173392561265
}, {
coefAlpha: 4.702 * Math.pow(10, -7),
coefBeta: 7.024 * Math.pow(10, -10),
upperBound: 1176405323219
}, {
coefAlpha: 5.338 * Math.pow(10, 1),
coefBeta: 2.425 * Math.pow(10, -10),
upperBound: 1182930300850
}, {
coefAlpha: 8.255 * Math.pow(10, 3),
coefBeta: 1.349 * Math.pow(10, -10),
upperBound: 1193299359828
}, {
coefAlpha: 2.496 * Math.pow(10, 6),
coefBeta: 3.509 * Math.pow(10, -11),
upperBound: 1241622616806
}, {
coefAlpha: 2.907 * Math.pow(10, 5),
coefBeta: 5.546 * Math.pow(10, -11),
upperBound: 1283088065116
}, {
coefAlpha: 5.206 * Math.pow(10, 4),
coefBeta: 6.716 * Math.pow(10, -11),
upperBound: 1291075200000
}, {
coefAlpha: 8.329 * Math.pow(10, 4),
coefBeta: 6.521 * Math.pow(10, -11),
upperBound: 1292241600000
}, {
coefAlpha: 8.396 * Math.pow(10, 4),
coefBeta: 6.541 * Math.pow(10, -11),
upperBound: 1307576237376
}, {
coefAlpha: 7.746 * Math.pow(10, 4),
coefBeta: 6.588 * Math.pow(10, -11),
upperBound: 1313586050187
}, {
coefAlpha: 8.798 * Math.pow(10, 6),
coefBeta: 3.922 * Math.pow(10, -11),
upperBound: 1340572542928
}, {
coefAlpha: 2.693 * Math.pow(10, 8),
coefBeta: 2.249 * Math.pow(10, -11),
upperBound: 1373049162025
}, {
coefAlpha: 1.225 * Math.pow(10, 9),
coefBeta: 1.610 * Math.pow(10, -11),
upperBound: Number.POSITIVE_INFINITY
},
];
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;
document.querySelector('body').appendChild(loadingNotify);
var next = get_next(start_url);
history.pushState("", "", next);
console.log('next: ' + next);
var x = new XMLHttpRequest();
x.onload = function() {
if (x.status <= 200 && x.status < 300) {
load(x);
} else {
error();
next_page_load();
}
};
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));
var docs = get_next_elements(htmlDoc);
if (!docs.length) {
error();
return next_page_load();
}
target_rewrite(docs);
img_cache(docs);
docs = docs.map(function(doc) {
return insert_parent.insertBefore(document.importNode(doc, true), insert_point);
});
loading = false;
document.querySelector('#endlessSummerLoading').remove();
State = true;
}
function get_next_elements(doc) {
var r = doc.evaluate('id("posts")/li[div[starts-with(@id, "post_")]]', 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 target_rewrite(docs) {
docs.forEach(function(doc) {
var as = doc.getElementsByTagName('a');
for (var i = 0, l = as.length; i < l; i++) {
var a = as[i],
_a = a.getAttribute('href');
if (_a && !/^javascript:/.test(_a) && !/^#/.test(_a)) a.setAttribute('target', '_blank');
}
});
}
function img_cache(docs) {
docs.forEach(function(doc) {
var is = doc.getElementsByTagName('img');
for (var i = 0, l = is.length; i < l; i++) {
var img = new Image();
img.src = is[i].src;
}
});
}
function error() {
State = false;
num = 2; // /dashboard/40超えたぐらいからどうも500エラーが頻発するので
return console.log('error');
}
function terminate() {
State = false;
return console.log('terminate');
}
function get_latest_id(doc) {
return doc.evaluate('number(substring-after(id("posts")/li/div[starts-with(@id, "post_")]/@id,"post_"))', doc, null, XPathResult.NUMBER_TYPE, null).numberValue;
}
function get_next(url) {
var ramdom_id = draw(oldest_id, latest_id);
var x = /(?:\/dashboard|(?:\/blog\/[-\w]+)?\/show\/\w+|\/blog\/[-\w]+)/.exec(url)[0] + '/' + num + '?offset=' + ramdom_id;
num += 1;
return x;
}
})();