AO3: [Wrangling] Edit Tag page cleanup

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

Version au 09/10/2022. Voir la dernière version.

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name         AO3: [Wrangling] Edit Tag page cleanup
// @namespace    https://greatest.deepsurf.us/en/users/906106-escctrl
// @description  Removes descriptions and some fields from Edit Tag pages to avoid wrangling accidents
// @author       escctrl
// @version      4.4.1
// @match        *://*.archiveofourown.org/tags/*/edit
// @require      https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/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'; }
}