NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name AniDB — Combine Eps and Seen in MyList // @namespace AquaWolfGuy // @description Shows seen, collected, and total episode count in one column instead of two, and highlights new episodes. // @icon https://static.anidb.net/css/icons/touch/apple-touch-icon.png // @author AquaWolfGuy // @copyright 2019, AquaWolfGuy // @license GPL-3.0-only // @match https://anidb.net/*/mylist* // @version 1.0.0 // @grant none // @run-at document-end // ==/UserScript== const matchRe = /^(.*?)\/(.*?)(?:\+(.*))?$/; function handleRow(row) { if (row.querySelector("tr.eps_seen") !== null) { return; } const seenCell = row.querySelector("td.seen"); const epsCell = row.querySelector("td.eps"); let [, seenSeen, seenHave, seenSpecial] = seenCell.textContent.trim().match(matchRe); let [, epsHave, epsTotal, epsSpecial ] = epsCell .textContent.trim().match(matchRe); if (seenHave !== epsHave) { console.error("Inconsistent entry. %s !== %s.", seenHave, epsHave, row); return; } if (seenSeen !== seenHave) { if (seenSeen < seenHave-1) { seenSeen = "<b>" + seenSeen + "</b>"; } seenHave = epsHave = "<b>" + seenHave + "</b>"; } if (seenSpecial !== epsSpecial) { if (seenSpecial && seenSpecial < epsSpecial-1) { seenSpecial = "<b>" + seenSpecial + "</b>"; } if (epsSpecial) { epsSpecial = "<b>" + epsSpecial + "</b>"; } } const seen = seenSeen + ((seenSpecial) ? ("+" + seenSpecial) : ""); const have = seenHave + ((epsSpecial ) ? ("+" + epsSpecial ) : ""); const total = epsTotal; const newCell = document.createElement("TD"); newCell.classList = "stats eps_seen" newCell.innerHTML = seen + " / " + have + " / " + total; epsCell.style.display = "none"; if (seenCell.nextElementSibling === epsCell || epsCell.nextElementSibling === seenCell) { newCell.colSpan = 2; seenCell.style.display = "none"; } else { seenCell.innerText = ""; } row.insertBefore(newCell, seenCell); } function handleMutation(mutationList) { for (const mutationRecord of mutationList) { console.log(mutationRecord); for (const row of mutationRecord.addedNodes) { try { handleRow(row); } catch (error) { console.error(error); } } } } const mylist = document.querySelector(".mylist_list #animelist tbody"); if (mylist !== null) { new MutationObserver(handleMutation).observe(mylist, {childList: true}); for (const row of mylist.children) { try { handleRow(row); } catch (error) { console.error(error); } } }