count instances of a term or terms in works from AO3 search pages
// ==UserScript==
// @name How many times does this character show up in this fic?
// @namespace http://tampermonkey.net/
// @version 0.3
// @description count instances of a term or terms in works from AO3 search pages
// @author exuvia
// @match https://archiveofourown.org/tags/*/works*
// @match https://archiveofourown.org/works?*
// @icon http://archiveofourown.org/favicon.ico
// @grant none
// ==/UserScript==
(function() {
//OPTIONS: Edit these!
const matchstrings = ["Term1","Term2","Term3"] //Change this to the term(s) you want to search for, ["term"] for one term
const matchcase = false; //Case sensitivity
const autocount = true; //Might get you "Retry Later"-temporary locked out of AO3 for sending too many requests. Change to false if it causes problems, or you want to click the count links manually.
//END OPTIONS
Array.from(document.querySelectorAll(".stats")).forEach((statblock,i) => {
let workID = statblock.parentElement.id.replace("work_","");
let ele = document.createElement("a");
ele.innerText = "Count";
ele.style.fontWeight = "bold";
ele.onclick = () => {
ele.innerText = "Working...";
ele.style.borderBottom = "initial";
ele.style.fontWeight = "";
let xhr = new XMLHttpRequest(); //send a request to AO3 for the fic's information, most of the 2 seconds of 'WORKING' wait time is for AO3 to respond
//start_time = new Date().getTime();
xhr.responseType = "document";
xhr.open("GET", "/works/" + workID + "?view_full_work=true", true);
xhr.onload = function() {
ele.innerText = ""
matchstrings.forEach(matchstring => {
const myPromise = new Promise((resolve, reject) => {
if (this.readyState == 4 && xhr.status === 200){
let matchreg = (matchcase) ? new RegExp(matchstring,'g') : new RegExp(matchstring,'gi');
const length = (xhr.responseXML.querySelectorAll("#chapters")[0].innerText.match(matchreg)|| []).length;
resolve(length);
//console.log('This request took '+(new Date().getTime() - start_time)+' ms')
}
else reject();
}).then((resolve) =>{
let ddcontainer = document.createElement("dd");
ddcontainer.innerText = " " + matchstring + ": " + resolve
ele.appendChild(ddcontainer)
ele.onclick = ""
}).catch((err) =>{
console.log(err)
ele.innerText += "REQUEST FAILED"
});
})
};
xhr.send();
}
let ddcontainer = document.createElement("dd");
statblock.appendChild(ddcontainer);
ddcontainer.appendChild(ele);
setTimeout(()=>ele.click(),3000*i) //clicks Count every 3 seconds. Decrease to have it autoclick faster (but might get you locked out with "Retry Later" faster)
})
})();