// ==UserScript== // @name How many times does this character show up in this fic? // @namespace http://tampermonkey.net/ // @version 0.1 // @description count instances of a term 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 // @downloadURL none // ==/UserScript== (function() { //OPTIONS: Edit these! const matchstr = "search for this string" //Change this to the term you want to search for const matchcase = true; //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 const matchreg = (matchcase) ? new RegExp(matchstr,'gi') : new RegExp(matchstr,'g'); Array.from(document.querySelectorAll(".stats")).forEach((statblock,i) => { const 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 = ""; const myPromise = new Promise((resolve, reject) => { 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() { if (this.readyState == 4 && xhr.status === 200){ 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(); }; xhr.send(); }).then((resolve) => ele.innerText = matchstr + ": " + resolve).catch((err) => ele.innerText = "REQUEST FAILED"); } let ddcontainer = document.createElement("dd"); statblock.appendChild(ddcontainer); ddcontainer.appendChild(ele); setTimeout(()=>ele.click(),1000*i) //clicks Count every 1000 milliseconds. Decrease to have it autoclick faster (but might get you locked out with "Retry Later" faster) }) })();