User:Terasail/ArticleInfo.js - Wikipedia


Article Images

Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump.
This code will be executed when previewing this page.

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.

/*<nowiki>
	Article Info
	Created by: Terasail
*/
// jshint esnext: false, esversion: 8
if (mw.config.get("skin").split("-")[0] == "vector") { //If skin is 'vector' or 'vector-2022'
	mw.loader.load('https://en.wikipedia.org/w/index.php?title=User:Terasail/ArticleInfo.css&action=raw&ctype=text/css', 'text/css');
	let wgUsername = mw.config.get("wgRelevantUserName");
	$.when(mw.loader.using('mediawiki.util'), $.ready).then(function () {
		if (wgUsername != null) {
			userInfo(wgUsername);
		}
		let wgAction = mw.config.get("wgAction");
		let wgArticleId = mw.config.get("wgRelevantArticleId");
		if (wgArticleId !== 0 && (wgAction === "view" || wgAction === "edit")) {
			pageInfo(wgArticleId);
		}
	});
}

async function userInfo(username) {
	let userGroups = {
		accountcreator: ["AC", "Account creator"],
		abusefilter: ["EFM", "Edit filter manager"],
		"abusefilter-helper": ["EFH", "Edit filter helper"],
		autopatrolled: ["AP", "Autopatrolled"],
		autoreviewer: ["AP", "Autopatrolled"],
		bot: ["BOT", "BOT"],
		bureaucrat: ["B", "Bureaucrat"],
		centralnoticeadmin: ["CNA", "Central notice administrator"],
		checkuser: ["CU", "Checkuser"],
		confirmed: ["C", "Confirmed"],
		eventcoordinator: ["EvCo", "Event coordinator"],
		extendedconfirmed: ["EC", "Extended confirmed"],
		extendedmover: ["PM", "Page mover"],
		filemover: ["FM", "File mover"],
		flood: ["Fl", "Flooder"],
		founder: ["Founder", "Founder"],
		"functioneer": ["F", "Functioneer"],
		"functionmaintainer": ["M", "Maintainer"],
		"global-renamer": ["GR", "Global renamer"],
		gwtoolset: ["GWT", ""],
		"image-reviewer": ["IR", "Image reviewer"],
		"import": ["IM", "Importer"],
		"interface-admin": ["IA", "Interface administrator"],
		"ipblock-exempt": ["IPBE", "IP block exempt"],
		"machinevision-tester": ["MVT", "Machine vision tester"],
		"massmessage-sender": ["MMS", "Mass message sender"],
		oauthadmin: ["OAA", "OAuth administrator"],
		patroller: ["P", "Patroller"],
		propertycreator: ["PC", "Property creator"],
		reviewer: ["PCR", "Pending changes reviewer"],
		rollbacker: ["R", "Rollbacker"],
		steward: ["S", "Steward"],
		suppress: ["O", "Oversighter"],
		sysop: ["A", "Administrator"],
		templateeditor: ["TE", "Template editor"],
		translationadmin: ["TA", "Translation administrator"],
		transwiki: ["TW", ""],
		uploader: ["U", "Uploader"],
		upwizcampeditors: ["UWC", ""],
		"wikifunctions-staff": ["WFS", "Wikifunctions Staff"],
	};
	let links = [$('#t-contributions'), $('#t-log')];
	mw.util.addPortlet('p-uinfo', 'User information', '#p-tb');
	mw.util.addPortletLink(
		'p-uinfo',
		"https://xtools.wmflabs.org/ec/" + mw.config.get("wgServerName") + "/" + username,
		'User xTools',
		't-uxtools',
		'Open xTools user information', '', ''
	);
	if ($('#t-userrights').length > 0) { //If a registered user
		mw.util.addPortletLink(
			'p-uinfo',
			"/wiki/Special:CentralAuth/" + username,
			'Global account',
			't-cauth',
			'View global account information', '', '#t-uxtools'
		);
		links.push($('#t-userrights'));
		//Add user info to the top of the page
		let userData = await aiApiGet({
			action: "query",
			list: "users",
			ususers: username,
			usprop: "editcount|groups|implicitgroups",
			format: "json"
		});
		userData = userData.query.users[0];
		let ubar = mw.util.addPortlet('p-ubar');
		$('#firstHeading').append(ubar);
		mw.util.addPortletLink(
			'p-ubar',
			"/wiki/Special:Contributions/" + username,
			'Edits: ' + addCommas(userData.editcount),
			't-uedits',
			'Special:Contributions', '', ''
		);
		let groups = userData.groups;
		groups = groups.slice(0, 0 - userData.implicitgroups.length);
		for (let i = 0; i < groups.length; i++) {
			let temp = userGroups[groups[i]];
			if (temp != undefined) {
				groups[i] = temp[0];
				// groups[i] = '<abbr title="' + temp[1] + '">' + temp[0] + '</abbr>';
			}
		}
		if (groups.length > 0) {
			mw.util.addPortletLink(
				'p-ubar',
				"/wiki/Special:UserRights/" + username,
				'Groups: ' + groups.toString().replaceAll(",", ", "),
				't-ugroups',
				'Special:UserRights', '', ''
			);
		}
	}
	$('#p-uinfo ul').append(links);
}

async function pageInfo(articleId) {
	let pXTools = mw.util.addPortletLink(
		'p-cactions',
		'https://xtools.wmflabs.org/articleinfo/' + mw.config.get("wgServerName") + '/' + encodeURIComponent(mw.config.get("wgRelevantPageName")),
		'Page xTools',
		't-pxtools',
		'Open xTools page information', '', ''
	);
	pXTools.children[0].target = "_blank";
	let editLocks = {
		move: ["4/44/Move-protection-shackle"],
		upload: ["d/d7/Upload-protection-shackle"],
		cascade: ["0/0f/Cascade-protection-shackle"],
		sysop: ["1/12/Full-protection-shackle-block", "c"],
		templateeditor: ["5/53/Template-protection-shackle"],
		extendedconfirmed: ["8/8c/Extended-protection-shackle"],
		autoconfirmed: ["1/1b/Semi-protection-shackle"]
	};
	let pbar = mw.util.addPortlet('p-pbar');
	$('#bodyContent').prepend(pbar);

	let pageBar = ["revs", "editors", "views", "watch", "created"];//"icons", 
	for (let a = 0; a < pageBar.length; a++) {
		mw.util.addPortletLink('p-pbar', '', '', 't-' + pageBar[a], '', '', '');
		$('#t-' + pageBar[a])[0].style = "display:none";
		$('#t-' + pageBar[a]).append($('#t-' + pageBar[a] + ' span'));
		$('#t-' + pageBar[a] + ' a').remove();
	}
	getPageviews(articleId); //Separate - Can throw errors on new pages
	//Separate - Speed up load: no need to wait on loading other requests
	getPageCounts();
	getAssessment(articleId); 

	let pageQuery = await aiApiGet({
		action: "query",
		prop: "info|revisions",
		pageids: articleId,
		inprop: "protection|watchers",
		rvprop: "timestamp|user",
		rvlimit: "1",
		rvdir: "newer",
		format: "json"
	});
	let pageInfo = pageQuery.query.pages[articleId];
	//Watchers
	if (pageInfo.watchers != null) {
		$('#t-watch span').append(addCommas(pageInfo.watchers) + ' <abbr title="Users with this page on their watchlist">Watchers</abbr>');
		$('#t-watch')[0].style = "";
	}
	//Page Protection
	let protections = pageInfo.protection;
	if (protections.length > 0) {
		let elemBefore = "#t-revs";
		if (document.getElementById('t-pasmt')) {
			elemBefore = "#t-pasmt";
		}
		let pProt = mw.util.addPortletLink(
			'p-pbar',
			mw.util.getUrl('Special:Log', {type: 'protect', page: mw.config.get('wgRelevantPageName')}),
			'',
			't-pprot',
			'Open page protection log', '', elemBefore
		);
		pProt.children[0].target = "_blank";
		$('#t-pprot span')[0].remove();
	}
	let cascade = false;
	for (let i = 0; i < protections.length; i++) {
		if (protections[i].source) {
			if (!cascade) {
				cascade = true;
				$('#t-pprot a').append(createImg(editLocks.cascade));
			}
		} else {
			if (protections[i].type == "edit") {
				$('#t-pprot a').append(createImg(editLocks[protections[i].level]));
			} else {
				$('#t-pprot a').append(createImg(editLocks[protections[i].type]));
			}
		}
	}
	//First page revision
	let pageRev = pageQuery.query.pages[articleId].revisions[0];
	let userQuery = await aiApiGet({
		action: "query",
		list: "users",
		ususers: pageRev.user,
		usprop: "editcount|groups|implicitgroups",
		format: "json"
	});
	userQuery = userQuery.query.users[0];
	let created = 'Created ' + new Date(pageRev.timestamp).toUTCString().slice(5, 16) + ', by ';
	created += '<a target="_blank" href="/wiki/User:' + pageRev.user + '">' + pageRev.user + '</a>';
	if (typeof (userQuery.editcount) !== "undefined" && typeof (userQuery.groups) !== "undefined") {
		created += ' (' + addCommas(userQuery.editcount) + " edits";
		let numRights = userQuery.groups.length - userQuery.implicitgroups.length;
		if (numRights > 0) {
			created += " | " + numRights + " group";
			if (numRights > 1) {
				created += "s";
			}
		}
		created += ")";
	}
	$('#t-created span').append(created);
	$('#t-created')[0].style = "";
}

async function getAssessment(articleId) {
	let assessments = {
		NA: ["6/6a/Symbol_na_class"],
		Draft: ["0/09/Symbol_draft_class"],
		Template: ["5/5c/Symbol_template_class"],
		Redirect: ["a/a2/Symbol_redirect_class", "c"],
		Project: ["7/72/Symbol_project_class"],
		Portal: ["e/e2/Symbol_portal_class"],
		File: ["9/9c/Symbol_file_class"],
		Disambig: ["2/2a/Symbol_dab_class", "c"],
		Category: ["9/96/Symbol_category_class"],
		List: ["d/db/Symbol_list_class"],
		Stub: ["f/f5/Symbol_stub_class"],
		Start: ["a/a4/Symbol_start_class"],
		C: ["e/e6/Symbol_c_class"],
		B: ["5/5f/Symbol_b_class"],
		A: ["2/25/Symbol_a_class", "c"],
		GA: ["9/94/Symbol_support_vote"],
		FM: ["b/bc/Featured_article_star", "c"],
		FL: ["b/bc/Featured_article_star", "c"],
		FA: ["b/bc/Featured_article_star", "c"],
		"": ["e/e0/Symbol_question"]
	};
	if (mw.config.get("wgServerName") == "en.wikipedia.org" && mw.config.get("wgCanonicalNamespace") == "") {
		pageQuery = await aiApiGet({
			action: "query",
			prop: "pageassessments",
			pageids: articleId,
			palimit: "1",
			format: "json"
		});
		let assessment = pageQuery.query.pages[articleId].pageassessments;
		if (assessment != null) {
			mw.util.addPortletLink('p-pbar', '', '', 't-pasmt','', '', '#t-revs');
			$('#t-pasmt a')[0].remove();
			$('#t-pasmt').append(createImg(assessments[Object.entries(assessment)[0][1].class]));
		}
	}
}

async function getPageviews(articleId) {
	let pageQuery = await aiApiGet({
		action: "query",
		prop: "pageviews",
		pageids: articleId,
		pvipdays: "30",
		format: "json"
	});
	let rawViews = Object.entries(pageQuery.query.pages[articleId].pageviews);
	let totalViews = 0;
	for (let i = 0; i < rawViews.length; i++) {
		if (typeof rawViews[i][1] == "number") {
			totalViews += rawViews[i][1];
		}
	}
	$('#t-views span').append(addCommas(totalViews) + ' <abbr title="Pageviews in the last 30 days">Pageviews</abbr>');
	$('#t-views')[0].style = "";
}

async function getPageCounts() {
	let fetchTarget = "https://" + mw.config.get("wgServerName") + "/w/rest.php/v1/page/" + encodeURIComponent(mw.config.get("wgRelevantPageName")) + "/history/counts/";
	let counts = [["edits", "Revision", "revs"], ["editors", "Editor", "editors"]];
	for (let j = 0; j < counts.length; j++) {
		let fetchResult = await fetch(fetchTarget + counts[j][0] + "?");
		fetchResult = await fetchResult.json();
		fetchResult = addCommas(fetchResult.count) + " " + counts[j][1];
		fetchResult = fetchResult.replace(/(?<=^30),000/, "k+").replace(/(?!^1 \w+)$/, "s");
		$('#t-' + counts[j][2] + ' span').append(fetchResult);
		$('#t-' + counts[j][2])[0].style = "";
	}
}

function aiApiGet(params) {
	return new Promise(function(resolve) {
		new mw.Api().get(params)
		.done(function (data) {resolve(data);})
		.fail(function (data) {console.error(data);});
	});
}

function addCommas(number) {
	if (typeof(number) == "number") {
		return number.toLocaleString('en-US');
	}
	return number;
}

function createImg(data) {
	if (data.length === 1) {
		data[1] = "en";
	} else if (data[1] === "c") {
		data[1] = "commons";
	}
	let imageStr = '<img src="//upload.wikimedia.org/wikipedia/' + data[1] + '/thumb/';
	imageStr += data[0] + ".svg/25px-" + data[0].slice(5);
	imageStr += '.svg.png" decoding="async" width="18" height="18"></a>';
	return imageStr;
}
//</nowiki>[[Category:Wikipedia scripts]]