AO3: [Wrangling] Edit Tag page cleanup

Removes descriptions and some fields from Edit Tag pages to avoid wrangling accidents

当前为 2022-09-04 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         AO3: [Wrangling] Edit Tag page cleanup
// @namespace    https://greasyfork.org/en/users/906106-escctrl
// @description  Removes descriptions and some fields from Edit Tag pages to avoid wrangling accidents
// @author       escctrl
// @version      4.4
// @match        *://*.archiveofourown.org/tags/*/edit
// @require      https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js
// @license      MIT
// ==/UserScript==

(function($) {
    'use strict';

    // remove all descriptions to save space. experienced wranglers know them by heart
    $('form#edit_tag dl dd p').not('.actions').hide();

    // store commonly referred to IDs to reduce DOM traversal, use JS instead of jQuery to speed it up
    const fieldCanonical = document.getElementById('tag_canonical');
    const fieldUnwrangleable = document.getElementById('tag_unwrangleable');
    const fieldSynonym = document.getElementById('tag_syn_string');

    // what's the status of my tag?
    const is_canonical = fieldCanonical.checked == true ? true : false;
    const is_unwrangleable = fieldUnwrangleable.checked == true ? true : false;
    const is_synonym = ($(fieldSynonym).prev().find("li.added").length == 1) ? true : false;

    // if the tag is two things at once, something was already incorrect, and we'd rather display all fields again to allow fixing it
    if (is_canonical && (is_unwrangleable || is_synonym) || (is_unwrangleable && is_synonym)) { return false; }


    // if the tag is not canonical, remove the metatag field
    if (!is_canonical) {
        $('dd[title="MetaTags"]').hide().prev().hide();
    }

    if (is_canonical) {
        // remove the unwrangleable button
        hide_fields(false, true, false);

        // disable the canonical checkbox if there is a metatag (to avoid the filter bug)
        if ($('#parent_MetaTag_associations_to_remove_checkboxes').length == 1) {
            $(fieldCanonical).attr("disabled", "disabled");
            $('input[name="tag[canonical]"]').attr("disabled", "disabled");
        }

        // remove the Add Subtags and Add Synonyms fields
        // if you don't want this, disable it by just adding // at the beginning of the next line
        hide_addsubsyn();
    }
    else if (is_synonym) {
        // remove the canonical and unwrangleable button
        hide_fields(true, true, false);

        // make the canonical tag itself an edit link like all other referenced tags on this page. then the Edit button can be removed
        var taglink = $(fieldSynonym).siblings('p.actions').hide().find('a').attr("href");
        $(fieldSynonym).siblings('ul.autocomplete').find('li.added').contents().first().wrap('<a class="tag" href="'+taglink+'"></a>');
    }
    else if (is_unwrangleable) {
        // remove canonical button and synonym field
        hide_fields(true, false, true);
    }
    else {
        document.getElementById('tag_syn_string_autocomplete').focus();
    }

    // if the tag is draft only, highlight the Draft field big and bright
    const taggings = [];

    // retrieve the numbers showing in the sidebar. we only need ones that are not linked (drafts, private bookmarks, total taggings)
    $('#dashboard.tag.wrangling ul:nth-of-type(2) li span').each( function() {
        // we grab the text, match only the number in it, convert it from string to int, and add it to the array
        taggings.push(parseInt($(this).text().match(/\d+/g)));
    });

    // [0] is drafts, [2] is the total taggings count. if they are equal, the tag is draft only
    // we check that total taggings are more than zero, or we'd end up highlighting every zero-taggings draft as well (zero drafts == zero total uses)
    if (taggings[0] == taggings[2] && taggings[2] > 0) {

        // Checks if using a dark mode by calculating the 'brightness' of the page background color
        const drafthighlight = lightOrDark(window.getComputedStyle(document.body).backgroundColor) == "dark" ? '#a08b2c' : 'yellow' ;

        $('#dashboard.tag.wrangling ul:nth-of-type(2) li:nth-of-type(2) span')
            .css('background-color', drafthighlight)
            .attr('title',"This tag is still in draft, you don't need to wrangle it yet");
    }

    // CONVENIENCE FUNCTIONS

    // hides the canonical/unwrangled checkboxes and synonym field
    function hide_fields(c, u, s) {
        if (c) { $(fieldCanonical).parent().hide().prev().hide(); }
        if (u) { $(fieldUnwrangleable).parent().hide().prev().hide(); }
        if (s) { $(fieldSynonym).parent().hide().prev().hide(); }
    }

    // hides the "add subtag" and "add synonym" fields - or the whole line if no sub/syn tags exist to save space
    function hide_addsubsyn() {
        var add_sub = $('dt').filter(() => $(this).text() == "SubTags");
        if ($('#child_SubTag_associations_to_remove_checkboxes').length == 0) add_sub.hide().next().hide();
        else add_sub.next().children('div[title="add tags"],h5.heading').hide();

        var add_syn = $('dt').filter(() => $(this).text() == "Synonyms");
        if ($('#child_Merger_associations_to_remove_checkboxes').length == 0) add_syn.hide().next().hide();
        else add_syn.next().children('div[title="add tags"],h5.heading').hide();

        // if there are neither subtags nor synonyms to display, hide the whole Child Tags fieldset
        if ($('#child_SubTag_associations_to_remove_checkboxes').length == 0 && $('#child_Merger_associations_to_remove_checkboxes').length == 0) {
            add_sub.parent().parent().hide();
        }
    }

})(jQuery);

// helper function to determine whether a color (the background in use) is light or dark
// https://awik.io/determine-color-bright-dark-using-javascript/
function lightOrDark(color) {

    // Variables for red, green, blue values
    var r, g, b, hsp;

    // Check the format of the color, HEX or RGB?
    if (color.match(/^rgb/)) {
        // If RGB --> store the red, green, blue values in separate variables
        color = color.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+(?:\.\d+)?))?\)$/);

        r = color[1];
        g = color[2];
        b = color[3];
    }
    else {
        // If hex --> Convert it to RGB: http://gist.github.com/983661
        color = +("0x" + color.slice(1).replace(
        color.length < 5 && /./g, '$&$&'));

        r = color >> 16;
        g = color >> 8 & 255;
        b = color & 255;
    }

    // HSP (Highly Sensitive Poo) equation from http://alienryderflex.com/hsp.html
    hsp = Math.sqrt( 0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b) );

    // Using the HSP value, determine whether the color is light or dark
    if (hsp>127.5) { return 'light'; }
    else { return 'dark'; }
}