Similar fix to your code but it doesnt use a double for loop so it does not run in exponential timeExpression wrote: ↑Fri Nov 26, 2021 2:48 amThanks for letting me know, looks like the HTML of topics change when they receive a reply. Here's the code that correctly handles new posts without replies. Original post will also have this same code.
Code: Select all
// ==UserScript== // @name Milovana Sorter // @version 0.3 // @description Sort Milovana topics by creation date // @author Expression // @match https://milovana.com/forum/viewforum.php?f=25 // @grant none // ==/UserScript== (function() { 'use strict'; function requestUrl(url) { /* send request to url and sends each post element to buildList processing */ const http = new XMLHttpRequest(); http.open("GET", url); http.send(); http.onreadystatechange = function() { if(this.readyState == 4 && this.status == 200) { var temp_element = document.createElement("html"); temp_element.innerHTML = http.responseText; var elementList = temp_element.getElementsByClassName("topiclist topics")[1].childNodes; elementList.forEach(buildList); } } } var post_arr = []; var display_arr = []; function getDate(el) { /* get date from element */ for(var i = 0; i < el.length; i++) { for(var j = 0; j < el[i].children.length; j++) { if(el[i].children[j].nodeName == "TIME") { return el[i].children[j].dateTime; } } } return "ERROR"; } var count = 0; function buildList(el, idx, arr) { /* scrapes data from topics and stores it in post_arr or display_arr for sticky topics, immediately storing stickies retains their order at the top*/ let match = /(?<=t\=)\d+(?=$)/; if(el.nodeType == 1) { try { count++; var className = el.className; var indexOffset = ((el.children[0].childNodes[1].children[0].className !== "list-inner") ? 1 : 0); var data = el.children[0].childNodes[1].children[0 + indexOffset].children; var url = data[0 + indexOffset].href; var postId = url.match(match)[0]; var postDate = Date.parse(getDate(data)); if(className.includes("sticky")) { display_arr.push(el); } else { post_arr.push([postDate, postId, el, className]); } } catch { return; } } } async function loop_requests() { /* requests first 5 pages of forum topics */ var loopIncrement = 50; var numPages = 5; var count = 0; var req_url = "https://milovana.com/forum/viewforum.php?f=25&start="; for(var i = 0; i <= numPages; i++) { count++; var postFrom = i * loopIncrement; if(count > 100) { break; } var url = req_url + postFrom; await requestUrl(url); } } loop_requests(); function replacePosts() { /* injects posts from an display_arr into the webpage */ document.getElementsByClassName("topiclist topics")[1].innerHTML = ""; for(var i = 0; i <= display_arr.length; i++) { try { document.getElementsByClassName("topiclist topics")[1].appendChild(display_arr[i]); } catch {} } } function getSortedElements() { /* sort elements in descending order by post date in post_arr and push them into display_arr */ var sorted = post_arr.sort(function(a,b) { return a[0]-b[0] }).reverse(); sorted.forEach(function(el, idx, arr) { display_arr.push(el[2]); }); replacePosts(display_arr); } var timeout = setInterval(function() { /* check if post_arr can be sorted by checking its length */ if(post_arr.length > 200) { getSortedElements(); clearInterval(timeout); } }, 100); })();
Code: Select all
// ==UserScript==
// @name Milovana Sorter
// @version 0.3
// @description Sort Milovana topics by creation date
// @author Expression
// @match https://milovana.com/forum/viewforum.php?f=25*
// @grant none
// ==/UserScript==
var active = document.getElementsByClassName("active")[0].innerText;
(function() {
'use strict';
var test = document.getElementsByClassName("topiclist topics")[1].childNodes;
var req_url = "https://milovana.com/forum/viewforum.php?f=25&start=";
function requestUrl(url) { /* send request to url */
const http = new XMLHttpRequest();
http.open("GET", url);
http.send();
http.onreadystatechange = function() {
if(this.readyState == 4 && this.status == 200) {
var temp_element = document.createElement("html");
temp_element.innerHTML = http.responseText;
var elementList = temp_element.getElementsByClassName("topiclist topics")[1].childNodes;
elementList.forEach(buildList);
}
}
}
var post_arr = [];
var display_arr = [];
function getDate(el) { /* get date from element */
for(var i = 0; i < el.length; i++) {
if(el[i].nodeName == "TIME") {
return el[i].dateTime;
}
}
throw new exception;
}
var count = 0;
function buildList(el, idx, arr) { /* scrapes data from topics and stores it in post_arr or display_arr for sticky topics, immediately storing stickies retains their order at the top*/
let match = /(?<=t\=)\d+(?=$)/;
if(el.nodeType == 1) {
try {
count++;
var className = el.className;
var indexOffset = ((el.children[0].childNodes[1].children[0].className !== "list-inner") ? 1 : 0);
var data = el.children[0].childNodes[1].children[0 + indexOffset].children;
var url = data[0 + indexOffset].href;
var postId = url.match(match)[0];
var l = 0;
try{
var postDate = Date.parse(getDate(data[4 + indexOffset].children));
}catch (e){
try{
var postDate = Date.parse(getDate(data[3 + indexOffset].children));
}catch(e){
console.log("ERROR!!!!!!");
}
}
if(className.includes("sticky")) {
display_arr.push(el);
} else {
post_arr.push([postDate, postId, el, className]);
}
} catch {
return;
}
}
}
async function loop_requests() { /* requests first 5 pages of forum topics */
var loopIncrement = 50;
var loopCount = 5;
var count = 0;
for(var i = 0; i < loopCount; i++) {
count++;
var postFrom = i * loopIncrement;
if(count > 100) {
break;
}
var url = req_url + postFrom;
await requestUrl(url);
}
}
loop_requests();
function replacePosts() { /* injects posts from an display_arr into the webpage */
var replace_list = document.getElementsByClassName("topiclist topics")[1].children;
for(var j = 0; j < 50*(active-1); j++){
display_arr.shift();
}
for(var i = 0; i < replace_list.length; i++) {
var new_post = document.createElement("li");
new_post.className = replace_list[i].className;
new_post.innerHTML = display_arr.shift().innerHTML;
replace_list[i].parentNode.replaceChild(new_post, replace_list[i]);
}
}
function getSortedElements() { /* sort elements in descending order by post date in post_arr and push them into display_arr */
var sorted = post_arr.sort(function(a,b) {
return a[0]-b[0]
}).reverse();
sorted.forEach(function(el, idx, arr) {
display_arr.push(el[2]);
});
replacePosts(display_arr);
}
var timeout = setInterval(function() { /* check if post_arr can be sorted by checking its length */
if(post_arr.length > 200) {
getSortedElements();
clearInterval(timeout);
}
}, 100);
})();