Greasy Fork

Greasy Fork is available in English.

How many times does this character show up in this fic?

count instances of a term or terms in works from AO3 search pages

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==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)
	})

})();