// ==UserScript==
// @name [s4s] interface
// @namespace s4s4s4s4s4s4s4s4s4s
// @include https://boards.4chan.org/s4s/thread/*
// @include http://boards.4chan.org/s4s/thread/*
// @version 1.041
// @grant none
// @author le fun css man AKA Doctor Worse Than Hitler
// @email doctorworsethanhitler@gmail.com
// @description Lets you view the greenposts.
// @downloadURL none
// ==/UserScript==
// basic post html
/////////////////////////////////////////////////////////////////////
//////// WANNA SET SOME STUFF UP HERE? GO FOR IT BBY! ///////////////
//////// IT IS THE CONFIGURATION SPOTS WOW ///////////////
var TEXT_COLOR = '#000'; // any css option for color is fine, eg #000, #000000, red, etc
/////////////////////////////////////////////////////////////////////
// (more to come for above)
//// global variables
// The basic HTML of a 4chan post. split into a couple of parts so we can remove the number field. The fields surrounded with &...& are fields to replace later with post text.
var baseHTML = '
>>
';
// the url of the interface.
var url = "https://funposting.online/interface/";
// the last good substite for a deleted post. used to correctly place the shadow posts whose [s4s] counterparts have been deleted
var lastGoodSubstitute;
// date nonsense
// ripped from https://www.elated.com/articles/working-with-dates/ along with the later date code.
var day_names = new Array();
day_names[day_names.length] = "Sun";
day_names[day_names.length] = "Mon";
day_names[day_names.length] = "Tue";
day_names[day_names.length] = "Wed";
day_names[day_names.length] = "Thu";
day_names[day_names.length] = "Fri";
day_names[day_names.length] = "Sat";
//// functions
// for sending a GET request, used to fetch post JSON from the server.
// ripped from https://stackoverflow.com/questions/247483/http-get-request-in-javascript
var HttpClient = function() {
this.get = function(aUrl, aCallback) {
var anHttpRequest = new XMLHttpRequest();
anHttpRequest.onreadystatechange = function() {
if (anHttpRequest.readyState == 4 && anHttpRequest.status == 200)
aCallback(anHttpRequest.responseText);
}
anHttpRequest.open("GET", aUrl, true);
anHttpRequest.send(null);
}
}
// add a post to the proper position in the thread
function addPost(aPost) {
// date options ripped from the site mentioned in the global vars sections
var options = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric'
};;
// build the shadow post's html
var posthtml = baseHTML;
if(aPost["options"] == "numberless") {
posthtml += baseHTML2;
posthtml = posthtml.replace(/\&AFTER_NO\&/g, "XXXXXX");
}
else {
posthtml += noHTML;
posthtml += baseHTML2
posthtml = posthtml.replace(/\&AFTER_NO\&/g, aPost["after_no"]);
}
posthtml = posthtml.replace(/\&ID\&/g, aPost["id"]);
posthtml = posthtml.replace(/\&TEXT\&/g, aPost["text"]);
posthtml = posthtml.replace(/\&TIMESTAMP\&/g, aPost["timestamp"]);
var d = new Date(aPost["timestamp"] * 1000);
posthtml = posthtml.replace(/\&DATE\&/g, d.toLocaleDateString() + ' (' + day_names[d.getDay()] + ') ' + d.toLocaleTimeString());
posthtml = posthtml.replace(/\&USERNAME\&/g, aPost["username"]);
// insert the post
var after_post = document.getElementById('pc' + aPost["after_no"]);
var post = document.createElement("div");
post.className = "postContainer replyContainer";
post.id = 'pc' + aPost["after_no"]; // if the last post in a thread isn't a valid post based on the id, when the thread updates the whole fugging thread is reloaded. this is a hacky work around sorry.
post.innerHTML = posthtml;
// add the post
if(document.getElementById('p'+aPost["after_no"]) !== null) {
after_post.parentNode.insertBefore(post, after_post.nextSibling);
}
else {
// an [s4s] post was deleted, so we'll search for an appropriate spot to insert this post.
// start at the last known existing post
// var currentPost = lastGoodSubstitute;
var currentPost = getThread();
// go through the remaining posts and find the most recent one that is not more recent than the post the interface post originally came after.
while(document.getElementById('pc'+currentPost).nextSibling !== null && document.getElementById('pc'+currentPost).nextSibling.id.split('pc')[1] < aPost["after_no"]
&& document.getElementById('pc'+currentPost).nextSibling.id.split('pc')[1] != currentPost)
{
currentPost = document.getElementById('pc'+currentPost).nextSibling.id.split('pc')[1];
}
after_post = document.getElementById('pc' + currentPost);
after_post.parentNode.insertBefore(post, after_post.nextSibling);
lastGoodSubstitute = currentPost;
}
return;
}
// what thread are we in?
function getThread() {
var thread = document.getElementsByClassName("thread")[0].id;
return thread.split('t')[1];
}
function LocalMain () {
// add in all the posts
var client = new HttpClient();
lastGoodSubstitute = getThread();
client.get(url+'get.php?thread=' + getThread(), function(response) {
var arr = JSON.parse(response);
Object.keys(arr).forEach(function(k) {
addPost(arr[k]);
});
});
// add the posting form
var form = document.createElement("div");
form.innerHTML = ''
document.getElementsByClassName("thread")[0].parentNode.insertBefore(form, document.getElementsByClassName("thread")[0].nextSibling);
}
// run this stufffffff
window.addEventListener ("load", LocalMain, false);