AO3: [Wrangling] Edit Tag page cleanup

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

// ==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      5.0
// @match        *://*.archiveofourown.org/tags/*/edit
// @require      https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js
// @require      https://update.greasyfork.org/scripts/491888/1355841/Light%20or%20Dark.js
// @license      MIT
// ==/UserScript==
 
/* eslint-disable no-multi-spaces */
/* global jQuery, lightOrDark */

(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
    if (!is_canonical) {
        $('dd[title="MetaTags"]').hide().prev().hide(); // remove the metatag field
		
		if ($('form#edit_tag fieldset:first-of-type dl dd:nth-of-type(3) strong').text() === "Fandom") { // on fandoms remove the fandom signup link
            if (is_synonym) $('a[href*="/tag_wranglers?"]').hide().before("To assign this fandom to yourself, go to the canonical tag it's synned to.");
            else $('a[href*="/tag_wranglers?"]').hide().before("You can't assign this fandom to yourself because the tag is not canonical.");
        }
    }
 
    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).prop("disabled", true);

            // if the metatags get selected for deletion, let the canonical checkbox be edited too
            $('#parent_MetaTag_associations_to_remove_checkboxes').on('change', 'input[type="checkbox"]', () => {
                if ($('#parent_MetaTag_associations_to_remove_checkboxes').find('input[type="checkbox"]').not(':checked').length === 0) $(fieldCanonical).prop("disabled", false);
                else $(fieldCanonical).prop('checked', true).prop("disabled", true);
            });
        }
 
        // remove the Add Subtags and Add Synonyms fields
        // there's a button to show the fields when you need them, but if you don't want this at all, add // 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)));
    });
 
    // 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' ;
 
    // [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 the draft entry on every zero-taggings tag as well
    if (taggings[0] == taggings[2] && taggings[2] > 0) {
        $('#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");
    }
    // if the tag isn't in use anymore...
    else if (taggings[2] == 0 && is_synonym) {
        $('#dashboard.tag.wrangling ul:nth-of-type(2) li:nth-of-type(6) span')
            .css('background-color', drafthighlight)
            .attr('title',"This tag is unused, you can try to let it rake");
    }
 
    // 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() {
        let dd_sub = $('#tag_sub_tag_string').parentsUntil('dd').parent();      // the <dd> containing the subtags
        let dd_syn = $('#tag_merger_string').parentsUntil('dd').parent();       // the <dd> containing the synonyms

        if ($('#child_SubTag_associations_to_remove_checkboxes').length == 0) dd_sub.hide().addClass('cleanup-togglevis').prev().hide().addClass('cleanup-togglevis');
        else dd_sub.children('div[title="add tags"],h5.heading').hide().addClass('cleanup-togglevis'); // if there are subtags currently, hide only the Add input

        if ($('#child_Merger_associations_to_remove_checkboxes').length == 0) dd_syn.hide().addClass('cleanup-togglevis').prev().hide().addClass('cleanup-togglevis');
        else dd_syn.children('div[title="add tags"],h5.heading').hide().addClass('cleanup-togglevis'); // if there are synonyms currently, hide only the Add input

        // if there's nothing currently to show in this <dl>, hide the whole <dl> so the box isn't bigger than the remaining buttons
        if ($(dd_sub).parent().children(':visible').length === 0) $(dd_sub).parent().hide().addClass('cleanup-togglevis');

        // add a button to show those hidden fields again, so people can still add them from this canonical (if that's their workflow)
        dd_sub.parent().parent().children('p.actions').prepend(`<a href="javascript:void(0)" id="cleanup-toggle">Add Subtags or Synonyms</a>`);
        $('#cleanup-toggle').on('click', () => {
            $('.cleanup-togglevis').show();
			$('#cleanup-toggle').hide();
        });
    }
 
})(jQuery);