您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds groups of shortcuts to assign tags to related fandoms more quickly.
// ==UserScript== // @name AO3: [Wrangling] Fandom Assignment Shortcut Groups // @description Adds groups of shortcuts to assign tags to related fandoms more quickly. // @version 1.4 // @author Nexidava (original by kaerstyne, contributions by raining_kittens, escctrl) // @namespace https://gf.qytechs.cn/en/users/725254 // @license GPL-3.0 <https://www.gnu.org/licenses/gpl.html> // @match *://*.archiveofourown.org/tags/*/edit // @match *://*.archiveofourown.org/tags/*/wrangle* // @match *://*.archiveofourown.org/tags/search* // @require https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js // @grant none // ==/UserScript== // CONFIG // !! MAKE SURE TO COPY THIS SOMEWHERE SAFE BEFORE UPDATING !! // configure custom fandom group associations // these strings should be the canonical names of fandoms // when a current or suggested fandom matches a set, all fandoms from that set will be inserted at the beginning of the list of fandoms, in the order listed here // when a current or suggested fandom matches the first subarray of a nested array, all fandoms from the second subarray will be inserted var fandom_sets = [ [ "Fire Emblem: Fuukasetsugetsu | Fire Emblem: Three Houses", "Fire Emblem Musou: Fuukasetsugetsu | Fire Emblem Warriors: Three Hopes", "Fire Emblem Series", ], [ // show Hololive and VShojo in VSAC without showing Hololive in VShojo and vice-versa [ "Virtual Streamer Animated Characters" ], [ "Hololive (Virtual Streamers)", "VShojo (Virtual Streamers)", ] ], [ // show VSAC in Hololive and VShojo without showing Hololive in VShojo and vice-versa [ "Hololive (Virtual Streamers)", "VShojo (Virtual Streamers)", ], [ "Virtual Streamer Animated Characters" ], ], ] // always append these fandoms to the suggested list, regardless of current or tagged fandoms var always_fandoms = [ "No Fandom", "Original Work", ] // only display the last pipe of fandoms if true // show the full fandom names if false var last_pipe_only = true // further customize nicknames with canonical:nickname pairs // these nicknames will appear exactly as written, ignoring last_pipe_only (and can therefore be used to selectively disable it) var custom_nicknames = { "The Locked Tomb Series | Gideon the Ninth Series - Tamsyn Muir": "The Locked Tomb Series", "Hourou Musuko | Wandering Son": "Hourou Musuko | Wandering Son", } // enable for tag search var do_tag_search = false // fandom list for tag search var tag_search_fandoms = [ "No Fandom", ] // CODE // construct sets fandom_sets = fandom_sets.map(set => { if (Array.isArray(set[0])) { return [new Set(set[0]), new Set(set[1])] } else { let temp = new Set(set) return [temp, temp] } }) // helper functions function encodeTagURL(tag) { return "https://archiveofourown.org/tags/" + encodeURI(tag).replace("/", "*s*").replace(".", "*d*").replace("#", "*h*").replace("?", "*q*").replace("&", "*a*") + "/edit"; }; function intersect(a, b) { return new Set(Array.from(a).filter(x => b.has(x))); } function union(a, b) { return new Set([...a, ...b]); } function format_fandom(string) { return custom_nicknames[string] || (last_pipe_only ? string.split(" | ").slice(-1)[0] : string) } function get_fandom_groups(current_fandoms) { var new_fandoms = new Set(current_fandoms) for (let fandom_set of fandom_sets.reverse()) { // if current fandom in a set, add all fandoms from the set if (intersect(fandom_set[0], current_fandoms).size !== 0) { // place disjoint sets after initial entry, otherwise before if (fandom_set[0] === fandom_set[1]) { new_fandoms = union(fandom_set[1], new_fandoms); } else { new_fandoms = union(new_fandoms, fandom_set[1]); } } } return union(new_fandoms, always_fandoms) } (function($) { // which page is this? var page_url = window.location.pathname; // unwrangled bin if (page_url.includes("/wrangle")) { // add shortcut checkboxes var current_fandom = $("h2.heading a").text(); var fandom_shortcuts = $('<ul class="filters" style="padding-bottom: .643em;"></ul>'); var suggested_fandoms = new Set([current_fandom]); suggested_fandoms = get_fandom_groups(suggested_fandoms) for (let fandom of suggested_fandoms) { var escaped_fandom = fandom.replace(/"/g, """); fandom_shortcuts.append('<li style="display: inline-block; margin: 0.1em 0"><label>' + '<input type="checkbox" name="fandom_shortcut" value="' + escaped_fandom + '">' + '<span class="indicator" aria-hidden="true"></span>' + '<span>' + format_fandom(fandom) + '</span>' + '</label></li>'); } $("dd[title='wrangle to fandom(s)']").prepend(fandom_shortcuts); // deselect any previously selected fandoms when selecting a new fandom $("input[name='fandom_shortcut']").change(function() { $("li.added.tag").remove(); $("input#fandom_string").val(""); }); // add fandom on form submit $("form#wrangulator").submit(function() { var selected_fandoms = $("input[name='fandom_shortcut']:checked").map((i,v) => v.value).toArray().join(",") if (selected_fandoms) { var fandom_input = $("input#fandom_string"); var existing_fandoms = fandom_input.val(); var separator = existing_fandoms == "" ? "" : ","; fandom_input.val(existing_fandoms + separator + selected_fandoms); } }); // tag edit page } else if (page_url.includes("/edit")) { function create_fandom_checkbox(name) { const escaped_name = name.replace(/"/g, """); return $("<li></li>").html(`<label> <input type="checkbox" name="fandom_shortcuts" value="${escaped_name}"> <span class="indicator" aria-hidden="true"></span> <span><a class="tag" href="${encodeTagURL(name)}">${format_fandom(name)}</a></span> </label>`); } // add shortcut checkboxes const fandom_list = $("dt:contains('Suggested Fandoms')").next().find("ul"); fandom_list.addClass("filters"); var suggested_fandoms = new Set($("dt:contains('Suggested Fandoms')").next().find("li").map(function() { return $(this).text(); }).get()); suggested_fandoms = get_fandom_groups(suggested_fandoms) fandom_list.html(Array.from(suggested_fandoms).map(create_fandom_checkbox)); // add fandoms on form submit $("form#edit_tag").submit(function() { var selected_fandoms = $("input[name='fandom_shortcuts']:checked").map(function() { return $(this).val(); }).toArray().join(); var fandom_input = $("input#tag_fandom_string"); var existing_fandoms = fandom_input.val(); var separator = existing_fandoms == "" ? "" : "," fandom_input.val(existing_fandoms + separator + selected_fandoms); }); // tag search page } else if (page_url.includes("/search") && do_tag_search && tag_search_fandoms) { var fandom_tickies = $('<ul class="filters" style="padding-top: .643em;"></ul>'); for (let fandom of tag_search_fandoms) { var escaped_name = fandom.replace(/"/g, """); fandom_tickies.append('<li style="display: inline-block; margin: 0.1em 0;"><label>' + '<input type="checkbox" name="fandom_shortcut" value="' + escaped_name + '">' + '<span class="indicator" aria-hidden="true"></span>' + '<span>' + fandom + '</span>' + '</label></li>'); } $("#tag_search_fandoms_autocomplete").parent().parent().prepend(fandom_tickies); // deselect any previously selected fandoms when selecting a new fandom $("input[name='fandom_shortcut']").change(function() { $("li.added.tag").remove(); }); // add fandom on form submit $("form#new_tag_search").submit(function() { var search_fandoms = $("input[name='fandom_shortcut']:checked").map((i,e) => e.value).toArray() // get existing fandom filters from added tags since input#tag_search_fandoms doesn't reflect removed tags $("li.added.tag").contents(":not(span)").map((i,e)=>search_fandoms.push(e.data.trim())) // filter empty values and duplicates search_fandoms = [...new Set(search_fandoms)].filter(e => e) $("input#tag_search_fandoms").val(search_fandoms.join(",")); }); } })(jQuery);
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址