AO3: [Wrangling] Fandom Assignment Shortcut Groups

Adds groups of shortcuts to assign tags to related fandoms more quickly.

当前为 2023-01-16 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         AO3: [Wrangling] Fandom Assignment Shortcut Groups
// @description  Adds groups of shortcuts to assign tags to related fandoms more quickly.
// @version      1.21

// @author       Nexidava (original by kaerstyne)
// @namespace    https://greasyfork.org/en/users/725254
// @license      GPL-3.0 <https://www.gnu.org/licenses/gpl.html>

// @match        *://*.archiveofourown.org/tags/*/edit
// @match        *://*.archiveofourown.org/tags/*/wrangle*
// @require      https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js
// @grant        none
// ==/UserScript==


// CONFIG

// configure custom fandom group associations
// 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
// these strings should be the canonical names of fandoms
var fandom_sets = [
    [
        "Fire Emblem: Fuukasetsugetsu | Fire Emblem: Three Houses",
        "Fire Emblem Musou: Fuukasetsugetsu | Fire Emblem Warriors: Three Hopes",
        "Fire Emblem Series",
    ],
    [
        "Hololive (Virtual Streamers)",
        "Virtual Streamer Animated Characters",
    ],
    [
        "재앙급 영웅님이 귀환하셨다 - 산지직송| The Return of the Disaster-Class Hero - SAN.G",
        "재앙급 영웅님이 귀환하셨다 | The Return of the Disaster-Class Hero (Webcomic)",
    ],
]

// 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",
}


// CODE

// convert arrays to Sets
fandom_sets = fandom_sets.map(set => new Set(set))

// 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, current_fandoms).size !== 0) {
            new_fandoms = union(fandom_set, new_fandoms);
        }
    }
    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, "&quot;");
            fandom_shortcuts.append('<li style="display: inline"><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, "&quot;");
            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);
        });
    }

})(jQuery);