AO3: [Wrangling] Edit Tag page cleanup

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

目前為 2022-09-04 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 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'; }
}