/*⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⣀⣠⣤⣶⣾⣿⣿⣿⣿⣦⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⣾⣿⡿⠟⠋⣹⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⢸⣿⣿⣿⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡄⠀⠀⠀⠀⠀⠀
⠀⠀⢀⣿⡿⠿⣿⣇⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⠀⠀⠀⠀
⠀⠀⠈⠁⠀⠀⣿⣿⣾⣿⣿⠉⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⠀⠀⠀
⠀⠀⠀⣠⣿⣦⣸⣿⣿⣿⣿⡀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⠀⠀
⠀⠀⠀⠈⠻⣿⣿⣿⣿⣿⣿⣿⣄⠀⠘⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠀⠀
⠀⠀⠀⠀⠀⠈⠻⣿⣿⣿⣿⣿⣿⣷⣄⠀⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠈⠻⣿⣿⡏⠹⣿⣿⣧⡀⠘⠛⠻⠿⣿⣿⣿⣿⣿⣿⠁⠀⠀
⠀⠀⠀⠀⠀⠈⠲⣄⡀⠈⠻⠃⠀⢻⣿⣿⣿⣶⣶⣶⣶⣶⣾⣿⣿⣿⡏⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠈⢿⣶⣄⡀⠀⠈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⡆⠀⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠇⠀⠀⢹⣿⣿⣿⣿⣿⣿⠿⠿⠟⠃⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
*/
// <nowiki>
// @ts-check
// Companion to markblocked - asynchronously marks users with talk page access revoked
// Chunks borrowed from [[User:Krinkle/Scripts/CVNSimpleOverlay_wiki.js]],
// [[User:GeneralNotability/ip-ext-info.js]], and [[MediaWiki:Gadget-markblocked.js]]
// Named "mark-rocked" as this script was forked from [[User:GeneralNotability/mark-locked.js]]
// By [[User:Frostly]]
/**
* Get all userlinks on the page
*
* @param {JQuery} $content page contents
* @return {Map} list of unique users on the page and their corresponding links
*/
function rockedUsers_getUsers($content) {
const userLinks = new Map();
// Get all aliases for user: & user_talk: (taken from markblocked)
const userNS = [];
for (const ns in mw.config.get( 'wgNamespaceIds' ) ) {
if (mw.config.get('wgNamespaceIds')[ns] === 2 || mw.config.get('wgNamespaceIds')[ns] === 3) {
userNS.push(mw.util.escapeRegExp(ns.replace(/_/g, ' ')) + ':');
}
}
// RegExp for all titles that are User:| User_talk: | Special:Contributions/ (for userscripts)
const userTitleRX = new RegExp('^(' + userNS.join('|') + '|Special:Contrib(?:ution)?s\\/|Special:CentralAuth\\/)+([^\\/#]+)$', 'i');
const articleRX = new RegExp(mw.config.get('wgArticlePath').replace('$1', '') + '([^#]+)');
const redlinkRX = new RegExp(mw.config.get('wgScript') + '\\?title=([^#&]+)');
$('a', $content).each(function () {
if (!$(this).attr('href')) {
// Ignore if the <a> doesn't have a href
return;
}
let articleTitleReMatch = articleRX.exec($(this).attr('href').toString());
if (!articleTitleReMatch) {
// Try the redlink check
articleTitleReMatch = redlinkRX.exec($(this).attr('href').toString());
if (!articleTitleReMatch) {
return;
}
}
let pgTitle;
try {
pgTitle = decodeURIComponent(articleTitleReMatch[1]).replace(/_/g, ' ');
} catch (error) {
// Happens sometimes on non-username paths, like if there's a slash in the path
return;
}
const userTitleReMatch = userTitleRX.exec(pgTitle);
if (!userTitleReMatch) {
return;
}
const username = userTitleReMatch[2];
if (!mw.util.isIPAddress(username, true)) {
if (!userLinks.get(username)) {
userLinks.set(username, []);
}
userLinks.get(username).push($(this));
}
});
return userLinks;
}
/**
* Check whether a user has talk page access revoked
*
* @param {string} user Username to check
*
* @return {Promise<boolean>} Whether the user in question has talk page access
*/
async function revokedUsers_isRevoked(user) {
user = user.charAt(0).toUpperCase() + user.slice(1)
const api = new mw.Api();
try {
const response = await api.get({
action: 'query',
list: 'blocks',
formatversion: '2',
bklimit: '1',
bkusers: user,
bkprop: 'flags'
});
if (response.query.blocks.length === 0) {
// If the length is 0, then we couldn't find the global user
return false;
}
// If the 'locked' field is present, then the user is locked
return 'allowusertalk' in response.query.blocks[0];
} catch (error) {
return false;
}
}
// On window load, get all the users on the page and check if they have talk page access
$.when( $.ready, mw.loader.using( 'mediawiki.util' ) ).then( function () {
mw.hook('wikipage.content').add(function ($content) {
const usersOnPage = rockedUsers_getUsers($content);
usersOnPage.forEach(async (val, key, _) => {
const userRocked = await revokedUsers_isRevoked(key);
if (userRocked) {
val.forEach(($link) => {
// $link.css({ opacity: 0.4, 'border-bottom-size': 'thick', 'border-bottom-style': 'dashed', 'border-bottom-color': 'red' });
// document.getElementById("myspan").textContent="newtext";
$link.text($link.text() + '🤫');
});
}
});
});
});
// </nowiki>