User:Andy M. Wang/massretarget.js

From Wikipedia, the free encyclopedia
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">
// massretarget
// by [[User:Andy M. Wang]]
// 1.0.2016.1111

$(document).ready(function() {
    "use strict";
    var currNs = mw.config.get("wgNamespaceNumber");
    if (mw.config.get("wgNamespaceNumber") >= 0)
        return; // not special page
    if (!normaliseTitle(mw.config.get("wgPageName")).startsWith("Special:WhatLinksHere/")) {
        return; // only at Special:WhatLinksHere/
    }

// from User:Kephir/gadgets/sagittarius.js
function normaliseTitle(title) {
    try {
        var t = new mw.Title(title);
        return t.getPrefixedText();
    } catch (e) {
        return null;
    }
}

/**
 * Returns redirect titles
 */
function findRedirects(destTitle) {
    if (destTitle === null || destTitle === '') {
        return { error:"Title given is null or empty." };
    }

    var redirData = JSON.parse($.ajax({ url:mw.util.wikiScript('api'), async:false,
        error: function (jsondata) {
            return { error:"Unable to search for redirects." }; },
        data: { action:'query', format:'json', titles:destTitle,
            prop:'redirects', rdlimit:100 }
    }).responseText).query.pages;

    var ret = {};
    ret.redirs = [];
    ret.redirList = "";
    for (var id in redirData) {
        ret.title = redirData[id].title;
        var count = 0;
        for (var k in redirData[id].redirects) {
            ++count;
            ret.redirs.push(redirData[id].redirects[k].title);
            ret.redirList += "  " + redirData[id].redirects[k].title + "\n";
        }

        if (count === 0) {
            return { error:"No redirects found." };
        }
        if (count > 99) {
            return { error:"Too many redirects. Consider AWB retargeting." };
        }

        ret.count = count;
        break;
    }
    return ret;
}

/**
 * Precondition: params non-null, given, valid
 */
function retargetRedir(redirTitle, source, dest) {
    var parseWikiText = JSON.parse($.ajax({ url:mw.util.wikiScript('api'), async:false,
        error: function (jsondata) { return null; },
        data: { action:'parse', format:'json', page:redirTitle,
            prop:'wikitext|parsetree' }
    }).responseText).parse.wikitext["*"];

    var re = /REDIRECT\s*\[\[(.*)\]\]/i;
    var found = re.exec(parseWikiText); // [0] full string matched, [1] first result
    if (found === null || found[0] === null || found[1] === null
            || found[0] === '' || found[1] === '') {
        return null;
    }

    if (found[1].includes("#")) {
        found[1] = found[1].substring(0, found[1].indexOf("#"));
    }

    var newWikiText = parseWikiText.replace(found[1], dest);
    var edittoken = mw.user.tokens.get( 'csrfToken' );
    var editSummary = "Redirected to [[" + dest + "]] (prev. [[" + found[1] + "]])";
    $.ajax({ url:mw.util.wikiScript('api'), async:false,
        error: function (jsondata) { return null; },
        type: 'POST',
        data: { action:'edit', format:'json', minor:true, recreate:false,
            title:redirTitle, text:newWikiText, summary:editSummary,
            token:edittoken }
    });

    return (redirTitle + " : \"" + found[1] + "\" → \"" + dest + "\"");
}

/**
 * Retarget redirs. Precondition: redirs, dest are non-null, given, valid
 */
function retargetRedirs(redirs, srcTitle, dest) {
    var count = 0;
    var retargets = "";
    var retargetk = "";
    var keepGoing = true;
    for (var k in redirs.redirs) {
        ++count;
        retargetk = retargetRedir(redirs.redirs[k], srcTitle, dest);
        if (retargetk === null && (!confirm(
                "Unable to retarget " + redirs.redirs[k] + ". Continue?"))) {
            return retargets;
        } else if (retargetk !== null) {
            retargets += retargetk + "\n";
        }

        if (count % 10 === 0) {
            alert("Done retargeting " + count + "/" + redirs.count + " redirects...");
        }
    }

    return retargets;
}

    mw.loader.using("mediawiki.util").then(function () {
    mw.util.addPortletLink('p-cactions', '#', "Mass retarget", "ca-massretarget", "Retarget redirects to another page");
    $("#ca-massretarget").click(function() {
        // get full page title (minus the guaranteed "Special:WhatLinksHere/" prefix
        var destTitle = normaliseTitle(mw.config.get("wgPageName")).substring(22);
        var destTitleRedirs = findRedirects(destTitle);
        if (destTitleRedirs.error !== undefined) {
            alert(destTitleRedirs.error); return;
        }

        var retargetTitle = normaliseTitle(prompt("Enter the full title to retarget "
            + destTitleRedirs.count + " redirect(s).\n\nList:\n" + destTitleRedirs.redirList));

        if (retargetTitle === destTitle) {
            alert("Retarget title identical to current title. Exiting."); return;
        }

        if (retargetTitle !== null && retargetTitle !== ''
                && confirm(destTitle + " → " + retargetTitle + "\nProceed on "
                    + destTitleRedirs.count + " redirects? (this will take a minute...)")) {
            var retargets = retargetRedirs(destTitleRedirs, destTitle, retargetTitle);
            alert(retargets);
        } else {
            alert("Aborted.");
        }
    });
    });
});
// </syntaxhighlight>