Advertisement
Guest User

AO3 author+tags quick-search 1.1

a guest
Oct 19th, 2019
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name            AO3 author+tags quick-search
  3. // @version     1.1
  4. // @include     https://archiveofourown.org/works*
  5. // ==/UserScript==
  6.  
  7. /* Adds extra links to the tags section at the top of an AO3 work page, redirecting user to any use of same tags by the same author.
  8. * ie. a quick way to find out if the writer of the great fic you just read has written anything else for the same fandom/pairing/trope/etc.
  9.  
  10. * If printCounts is set to 'true', code will also calculate and display the number of uses of each tag in the fandom/relationship/character sections,
  11. * though this will also make the links take longer to load, as code must pre-load each link individually. To limit load, I have not implemented this for freeform or other tags.
  12.  
  13. * Author-based search links are a bit of a hack, so the search tag WON'T be selected in the tags menu on the right.
  14. * I've added a subheading to identify the tag instead.
  15.  
  16. */
  17.  
  18. var quickSearchText = "*"; // text for new links - change this if you want something other than an * You can put <sup>TEXT</sup> to make it superscript
  19. var printCounts = true;          // setting this to false will prevent script for printing tag counts, which may decrease loading times and server load
  20.  
  21. var loc = location.href;
  22.  
  23. var href="https://archiveofourown.org/works?utf8=%E2%9C%93&commit=Sort+and+Filter&work_search[relationship_names]=";
  24. var workPage="https://archiveofourown.org/works/";
  25. var scriptTag = "&greasemonkey"; //tag to flag that we've clicked an author quicktag link
  26.  
  27. if (loc.includes(workPage)) {
  28.   // Story page, add extra links user-based search to each tag
  29.  
  30.   var h3=document.body.getElementsByClassName("byline heading");
  31.   var authors=h3.item(0).getElementsByTagName('a');
  32.   authors=parseAuthors(authors);
  33.  
  34.   var allTags=document.body.getElementsByClassName("work meta group").item(0);
  35.   var dds = allTags.getElementsByTagName('dd');
  36.  
  37.   var links = dds.item(1).getElementsByTagName('a');
  38.  
  39.   for (var j=0; j<dds.length; j++) {
  40.     var tags = dds.item(j);
  41.     if (getTagType(tags) == "stats") break;
  42.  
  43.     links = tags.getElementsByTagName('a');
  44.     for (var i=links.length-1; i>=0; i--) {
  45.  
  46.       for (var a=0; a<authors.length; a++) {
  47.  
  48.         var author=authors[a];
  49.         var tag = getTag(links.item(i).href);
  50.         var newHref = buildSearch(tag);
  51.  
  52.         var text = quickSearchText;
  53.         var newlink=document.createElement('span');
  54.         if (printCounts && printCountFor(tags)) {
  55.           var count = getNumFics(newHref);
  56.           if (count>1) {
  57.             text = "<b><sup>(" + count.toString() + ")<sup></b>";
  58.           }
  59.           else {
  60.             text = "<sup>(1)<sup></b>";
  61.           }
  62.         }
  63.         newlink.innerHTML = " <a href=\"" + newHref + "\">" + text + "</a>";
  64.  
  65.         links.item(i).parentNode.appendChild(newlink);
  66.       }
  67.     }
  68.   }
  69. }
  70.  
  71.  
  72. else if (loc.includes(scriptTag)) {
  73.   // Quicktags search results page, add title to show which tag is in use
  74.  
  75.   var sTag = getBetween("work_search[relationship_names]=", loc, "&user_id=");
  76.   var main = document.getElementById("main");
  77.   var heading = main.getElementsByClassName("heading").item(0);
  78.  
  79.   sTag = unformatTag(sTag);
  80.   sTag = " Author QuickSearch: " + sTag;
  81.   var span=document.createElement('h3');
  82.   span.innerHTML = sTag;
  83.  
  84.   heading.parentNode.insertBefore(span, heading.nextSibling);
  85. }
  86.  
  87. function getTagType(element) {
  88.   var name = element.className;
  89.   name = name.replace(" tags", "");
  90.   return name;
  91. }
  92.  
  93. //Limit tag counts to fandom, relationship and character tags
  94. function printCountFor(element) {
  95.   var name = getTagType(element);
  96.   var types = ["fandom","relationship","character"];
  97.   for (var i=0; i<types.length; i++) {
  98.     if (types[i] == name) return true;
  99.   }
  100.   return false;
  101.  
  102. }
  103.  
  104.  
  105. //Retrieve page as javascript object
  106. function getSourceAsDOM(url)
  107. {
  108.     var xmlhttp=new XMLHttpRequest();
  109.     xmlhttp.open("GET",url,false);
  110.     xmlhttp.send();
  111.     var parser=new DOMParser();
  112.     return parser.parseFromString(xmlhttp.responseText,"text/html");
  113. }
  114.  
  115. //Counts results of author+tag search
  116. function getNumFics(url) {
  117.   var results = getSourceAsDOM(url);
  118.   var works = results.getElementsByClassName("work index group")[0];
  119.  
  120.   if (works.children.length < 20) {
  121.       return works.children.length;
  122.   }
  123.  
  124.   var h=results.getElementsByTagName("h2");
  125.   if (h.length>0) {
  126.     h=h[0];
  127.       var text = h.textContent;
  128.     if (text.includes(" of ")) {
  129.       text = getBetween(" of ", text, " Works");
  130.       return text; //could convert this into an integer, but not much point
  131.     }
  132.   }
  133.     return 20;
  134. }
  135.  
  136. function parseAuthors(links) {
  137.   var authors = [""];
  138.   for (var i=0; i<links.length; i++) {
  139.     var text = links.item(i).toString();
  140.         authors[i] = getBetween("/users/", text, "/pseuds");
  141.   }
  142.   return authors;
  143. }
  144.  
  145.  
  146.  
  147. function getBetween(tag1, str, tag2) {
  148.     var ret = str.split(tag1);
  149.   if (ret.length<2) return "";
  150.   ret=ret[1];
  151.     ret = ret.split(tag2);
  152.   if (ret.length<1) return "";
  153.   ret = ret[0];
  154.   return ret;
  155. }
  156.  
  157. //Format tag to pass to search
  158. function getTag(href){
  159.   var tag = getBetween("/tags/", href, "/works");
  160.   tag = replaceAll(tag, "*s*","%2F");
  161.   tag = replaceAll(tag, "*d*",".");
  162.   tag = replaceAll(tag, "%20","+");
  163.   return tag;
  164. }
  165.  
  166. // Format tag from href for display in title
  167. function unformatTag(tag) {
  168.   tag = replaceAll(tag, "*s*","/");
  169.   tag = replaceAll(tag, "*a*","&");
  170.   tag = replaceAll(tag, "*d*",".");
  171.   tag = replaceAll(tag, "%2F","/");
  172.   tag = replaceAll(tag, "+", " ");
  173.   tag = replaceAll(tag, "%7C", "|");
  174.   tag = replaceAll(tag, "%22", "\"");
  175.   return tag;
  176. }
  177.  
  178. function replaceAll(str, search, replacement) {
  179.     return str.split(search).join(replacement);
  180. }
  181.  
  182. function buildSearch(tag){
  183.     var href="https://archiveofourown.org/works?utf8=%E2%9C%93&commit=Sort+and+Filter&work_search[relationship_names]="
  184.   href+=tag + "&user_id=" + author + scriptTag;
  185.   return href;
  186. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement