User:DarkMatterMan4500/mark-locked.js

Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: press Ctrl-F5, Mozilla: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Opera/Konqueror: press F5, Safari: hold down Shift + Alt while clicking Reload, Chrome: hold down Shift while clicking Reload.
// <nowiki>
// @ts-check
// Companion to markblocked - asynchronously marks locked users
// Chunks borrowed from [[User:Krinkle/Scripts/CVNSimpleOverlay_wiki.js]],
// [[User:GeneralNotability/ip-ext-info.js]], and [[MediaWiki:Gadget-markblocked.js]]

/**
 * 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 lockedUsers_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:Contributions' + '\\/)+([^\\/#]+)$', 'i' );
	const articleRX = new RegExp( mw.config.get( 'wgArticlePath' ).replace('$1', '') + '([^#]+)' );
	$('a', $content).each(function () {
		if (!$(this).attr('href')) {
			// Ignore if the <a> doesn't have a href
			return;
		}
		const articleTitleReMatch = articleRX.exec($(this).attr('href').toString());
		if (!articleTitleReMatch) {
			return;
		}
		const pgTitle = decodeURIComponent( articleTitleReMatch[1] ).replace( /_/g, ' ' );
		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 is locked
 *
 * @param {string} user Username to check
 *
 * @return {Promise<boolean>} Whether the user in question is locked
 */
async function lockedUsers_isLocked(user) {
	const api = new mw.Api();
	try {
		const response = await api.get({
			action: 'query',
			list: 'globalallusers',
			agulimit: '1',
			agufrom: user,
			aguto: user,
			aguprop: 'lockinfo'
		});
		if (response.query.globalallusers.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 'locked' in response.query.globalallusers[0];
	} catch (error) {
		return false;
	}
}

// On window load, get all the users on the page and check if they're blocked
$.when( $.ready, mw.loader.using( 'mediawiki.util' ) ).then( function () {
	mw.hook('wikipage.content').add(function ($content) {
		const usersOnPage = lockedUsers_getUsers($content);
		usersOnPage.forEach(async (val, key, _) => {
			const userLocked = await lockedUsers_isLocked(key);
			if (userLocked) {
				val.forEach(($link) => {
					$link.css({ opacity: 0.4, 'border-bottom-size': 'thick', 'border-bottom-style': 'dashed', 'border-bottom-color': 'red' });
				});
			}
		});
	});
});
// </nowiki>