User:RoySmith/tag-check.js

Today we are going to address a very important topic, User:RoySmith/tag-check.js, which has become relevant in different aspects of daily life. This issue has aroused the interest of many people and has generated an intense debate in society in general. User:RoySmith/tag-check.js is a topic that has been the subject of study, reflection and analysis by experts in various disciplines, who have dedicated time and effort to understanding its implications and consequences. Throughout this article, we will explore different perspectives on User:RoySmith/tag-check.js, examine its impact in different areas, and discuss possible solutions or approaches to effectively address this issue.
//
// Main function.
//
async function checkTags(content) {
    content.find("span.cuEntry").each(async function() {
        const userNode = $(this).find("a");
        const parseTree = await getParseTree("User:" + userNode.text);
        if (parseTree !== null) {
            const status = tagStatus(parseTree);
            if ('tagType' in status) {
                $(this).before("<span style=\"background-color:"
                               + status.color
                               + "; border:darkgrey solid 1px; padding:1px;\" title=\""
                               + status.tooltip
                               + "\">"
                               + status.tagType
                               + " </span>");
            }
        }
    });
};


//
// Given a page title (ex: "User:Foo"), return a Promise of a JSON
// parse tree.
//
// On any kind of error, null is returned.
//
async function getParseTree(pageTitle) {
    try {
        const page = await $.get('/api/rest_v1/page/html/' + pageTitle);
        const jsonText = findSpiTemplate(page);
        return JSON.parse(jsonText);
    } catch (error) {
        return null;
    }
};

//
// Given the parsoid text of a page, find the SPI-related template.
//
// Page is whatever a '/api/rest_v1/page/html/' API call returns.  The
// data-mw attribute for the template is returned as a JSON string.
//
// If the page contains multiple SPI templates, the first one is used.
//
function findSpiTemplate(page) {
    const $html = $($.parseHTML(page));
    const template = $html.find('').filter(function() {
        try {
            const data = JSON.parse($(this).attr('data-mw'));
            return data.match(/ock/);
        } catch(err) {
            return false;
        }
    });
    return template.attr('data-mw');
};


//
// Handle redirected template names.  This is playing whack-a-mole;
// it should really be handled on the server side.
//
function emulateRedirects(rawTemplateName) {
    switch(rawTemplateName) {
    case 'sockmaster':
        return 'sockpuppeteer';
    default:
        return rawTemplateName;
    }
}

//
// Return an object describing how to style a SPI tag indicator.
//
// tagType: "M" for a sockmater, "P" for a sockpuppet
// color: what color to make the box.
// tooltip: a text description of the type of tag
//
// If there is no SPI tag, an empty object is returned.
//
function tagStatus(parseTree) {
    const template = parseTree.parts.template;
    const rawTemplateName = template.target.wt.trim();
    const templateName = emulateRedirects(rawTemplateName).toLowerCase();
    let tagType = null;
    let typeParam = null;

    if (templateName == 'sockpuppeteer') {
        tagType = "M";
        const params = template.params;
        if ('1' in params) {
            typeParam = params.wt.trim();
        } else {
            typeParam = 'suspected';
        }
    } else if (templateName == 'sock' || templateName == 'sockpuppet') {
        tagType = "P";
        typeParam = template.params.wt.trim();
    } else if (templateName == 'checked sockpuppet') {
        tagType = "P";
        typeParam = 'confirmed';
    } else {
        return {};
    }

    if (typeParam == 'suspected') {
        return {
            tagType: tagType,
            color: "#ffffff",
            tooltip: "suspected"
        };
    }

    if (typeParam == 'blocked') {
        return {
            tagType: tagType,
            color: "#ffff66",
            tooltip: "blocked"
        };
    }
    if (typeParam == 'proven') {
        return {
            tagType: tagType,
            color: "#ffcc99",
            tooltip: "proven"
        };
    }
    if (typeParam == 'confirmed') {
        return {
            tagType: tagType,
            color: "#ff3300",
            tooltip: "confirmed"
        }
    }
    if (typeParam == 'banned') {
        return {
            tagType: tagType,
            color: "#7a00ff61",
            tooltip: "banned"
        }
    }
    return {
        tagType: tagType,
        color: "#ffffff",
        tooltip: "unknown"
    };
}

// There's probably a nicer way to do this.  The check for mw being undefined
// lets us import this file into QUnit for testing.
if (typeof mw !== "undefined") {
    // Cribbed from User:Writ Keeper/Scripts/cuStaleness.js
    mw.hook('wikipage.content').add(function (content) {
        const titleRegex = /Wikipedia:Sockpuppet_investigations\/+/;
        const sandboxRegex = /User:RoySmith\/sandbox/;
        //only use on a SPI page (or my sandbox for testing)
        const pageName = mw.config.get("wgPageName");
        if (titleRegex.test(pageName) || sandboxRegex.test(pageName)) {
            checkTags(content);
        }
    });
};