User:Sam Sailor/Scripts/GlobalUserToolbox.js

Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
// <syntaxhighlight lang="javascript">
// <nowiki>
/**
 * Global User Toolbox (GUT) automatically fetches and injects a template-based 
 * navigation toolbox (specifically {{User toolbox}}) onto user-related pages 
 * (User, Talk, and Subpages) to provide quick access to administrative and 
 * analytical tools for that specific user.
 * - Forked from [[User:Chlod/Scripts/GlobalUserToolbox.js]] ([[Special:PermanentLink/977522492]])
 * - Added: "default_state" option for template collapse/expand.
 * To customize this script, add the following block to your 
 * personal common.js ABOVE the line where you load the script:
 * ---------------------------------------------------------
   window.gutOptions = {
       "default_state": "collapsed", // Default: "expanded"
       "insert_at_top": true,        // Default: true (false = bottom)
       "include_userpages": true,    // Default: true
       "include_talkpages": true,    // Default: true
       "include_subpages": true,     // Default: true
       "include_talksubpages": true, // Default: true
       "ignore_existing": true       // Default: true (prevents duplicates)
   };
 * ---------------------------------------------------------
 */

(function () {
    const defaultOptions = {
        "include_userpages": true,
        "include_talkpages": true,
        "include_subpages": true,
        "include_talksubpages": true,
        "insert_at_top": true,
        "ignore_existing": true,
        "default_state": "expanded"
    };
    // Merge user-defined options from window.gutOptions with the defaults
    const gutOptions = Object.assign({}, defaultOptions, window.gutOptions || {});

    const isSubpage = mw.config.get("wgPageName").includes('/');
    const ns = mw.config.get("wgNamespaceNumber");
    const isUserNs = (ns === 2);
    const isUserTalkNs = (ns === 3);

    const shouldRun = (
        (gutOptions.include_userpages     && isUserNs     && !isSubpage) ||
        (gutOptions.include_talkpages     && isUserTalkNs && !isSubpage) ||
        (gutOptions.include_subpages      && isUserNs     &&  isSubpage) ||
        (gutOptions.include_talksubpages  && isUserTalkNs &&  isSubpage)
    );

    if (!shouldRun) return;

    const user = mw.config.get("wgTitle").split('/')[0];

    if (gutOptions.ignore_existing && (document.getElementById('gut_output') || document.getElementById(`User_toolbox_for_${user}`))) return;

    const api = new mw.Api();
    api.get({
        action: "parse",
        format: "json",
        // Using the dynamic state variable here
        text: `{{User_toolbox|state=${gutOptions.default_state}|1=${user}}}`,
        contentmodel: "wikitext",
        prop: "text",
        disablelimitreport: 1
    }).done(function (data) {
        if (!data?.parse?.text?.["*"]) {
            console.error("GUT: Failed to parse User_toolbox.");
            showError("GUT: Could not load user toolbox (empty or missing response).");
            return;
        }

        const html = data.parse.text["*"];
        const $container = $('<div id="gut_output"></div>').html(html);
        const $content = $("#mw-content-text");

        if (gutOptions.insert_at_top) {
            $content.prepend($container);
        } else {
            let $anchor = $content.find("#gut_bottom_anchor");
            if (!$anchor.length) {
                $anchor = $('<div id="gut_bottom_anchor"></div>');
                $content.append($anchor);
            }
            $anchor.before($container);
        }
    }).fail(function (error) {
        console.error("GUT: API request failed", error);
        showError("GUT: Could not load user toolbox (API request failed).");
    });

    function showError(message) {
        $("#mw-content-text").prepend(
            $('<div id="gut_error" style="color:var(--color-text-warning,#b85c00);padding:6px 10px;border:1px solid currentColor;border-radius:4px;font-size:13px;margin-bottom:8px"></div>')
                .text(message)
        );
    }
})();
// </nowiki>
// </syntaxhighlight>