User:1234qwer1234qwer4/shortdescs-in-category.js

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.
/**
 * Shows button on category pages to see short description of all pages in the category.
 * 
 * Look for a button saying "Show SDs" towards the right, above the list of pages.
 * 
 * Forking from [[User:SD0001/shortdescs-in-category.js]] to allow importing Wikidata descriptions.
 * Uses code from [[User:Qwerfjkl/scripts/unusedCategories.js]]
 * 
 * Do not use on redirects (yet)
 * 
 * <nowiki>
 */

$.ready.then(function() {

	if (mw.config.get('wgNamespaceNumber') !== 14) {
		return;
	}
	
	$('#mw-pages > p').append(
		$('<button>').text('Show SDs').attr('id', 'showSD-button').addClass('mw-ui-button').css('float', 'right').click(showsSDs)
	);

	if (location.href.indexOf('&showSD=y') !== -1) {
		showsSDs();
	}

});

function fixLinks(showingSDs) {
	if (showingSDs) {
		$('#mw-pages > a').each(function() {
			if (this.href.indexOf('#') !== -1) {
				this.href = this.href.replace(/#/, '&showSD=y#');
			} else {
				this.href += '&showSD=y';
			}
		});
	} else {
		$('#mw-pages > a').each(function() {
			this.href = this.href.replace(/&showSD=y/g, '');
		});
	}
}

function hideSDs(e) {
	if (e) e.preventDefault();
	
	fixLinks(false);
	$('#showSD-button').text('Show SDs').off('click').on('click', showsSDs);
	$('.cat-shortdesc-none, .cat-shortdesc-local, .cat-shortdesc-wikidata, .cat-shortdesc-wikidata-import').remove();
	
}

function showsSDs(e) {
	if (e) e.preventDefault();

	fixLinks(true);
	$('#showSD-button').text('Hide SDs').off('click').on('click', hideSDs);	
	
	mw.util.addCSS('.cat-shortdesc-none { color: red } .cat-shortdesc-wikidata { color: MediumVioletRed } .cat-shortdesc-wikidata-import {font-size:x-small; display:inline-block}');

	var titles = $('#mw-pages li').get().map(function(e) {
		var a = e.querySelector('a');
		return mw.Title.newFromText(a.textContent).getSubjectPage().toText();
	});

	var titleSets = arrayChunk(titles, 50);
	var api = new mw.Api();
	var wdApi = new mw.ForeignApi('https://www.wikidata.org/w/api.php', { anonymous: true });

	var promiseArr = titleSets.map(function(set) {
		return api.get({
			"action": "query",
			"format": "json",
			"prop": "description",
			"titles": set,
			"formatversion": "2",
		});
	});
	var promiseArrWd = titleSets.map(function(set) {
		return wdApi.get({
			"action": "wbgetentities",
			"sites": "enwiki",
			"titles": set,
			"props": "descriptions|sitelinks",
			"languages": "en",
			"sitefilter": "enwiki"
		});
	});

	$.when.apply($, promiseArr.concat(promiseArrWd)).then(function() {
		var descs = {};
		Array.prototype.slice.call(arguments).forEach(function(response) {
			var json = response[0];
			if (json.query) { // enwiki API output
				json.query.pages.forEach(function(pg) {
					descs[pg.title] = {
						value: pg.description
					};
				});		
			} else if (json.entities) { // wikidata API output
				$.each(json.entities, function(id, data) {
					var pagename = data.sitelinks && data.sitelinks.enwiki && data.sitelinks.enwiki.title;
					if (pagename) {
						var entry = descs[pagename];
						if (entry && !entry.value) {
							entry.value = data.descriptions && data.descriptions.en && data.descriptions.en.value;
							entry.wd = id;
						} 
					}
				});
			}
		});	
		attachDescriptions(descs);
	});
}

function attachDescriptions(descs) {
	$('#mw-pages li').get().forEach(function(e) {
		var a = e.querySelector('a');
		var title = mw.Title.newFromText(a.textContent).getSubjectPage().toText();
		if (!descs[title] || !descs[title].value) {
			$(e).append(
				$('<span>').text(' – no shortdesc')
					.addClass('cat-shortdesc-none')
			);
		} else if (!descs[title].wd) {
			$(e).append(
				$('<span>').text(' – ' + descs[title].value)
					.addClass('cat-shortdesc-local')
			);
		} else {
			var wd = descs[title].wd;
			$(e).append(
				$('<span>').text(' – ' + descs[title].value)
					.addClass('cat-shortdesc-wikidata')
			).append(
				$('<a>').text(' – Import')
					.addClass('cat-shortdesc-wikidata-import')
					.attr({title: "Import Wikidata description.", noPopup: 1, id: wd + "Import"})
			);
			$("#" + wd + "Import").click({"page":title,"desc":descs[title].value}, importSubmitS);
		}
	});
}

function importSubmitS(event){
	var page = event.data.page;
	var desc = event.data.desc;
	checkPageWikitextS(page,desc);
}

function checkPageWikitextS(page,desc) {
	var send_req = {
		action: 'expandtemplates',
		text: "{{:"+page+"}}",
		titles: page,
		prop: 'wikitext',
	};
	$.get( mw.config.get( 'wgScriptPath' ) + '/api.php', send_req, function( response ) {
		window.textToCheckForCategories = $( response ).find( '*' ).text();
		importSubmitS2(page,desc);
	});
}

function importSubmitS2(page,desc) {
	if (window.textToCheckForCategories.match(/Category:articles with short description/) != null) { // There's a match
    	mw.notify( page+" contains a short description, aborted.");
	    return;
	}
	desc1=desc.charAt(0).toUpperCase()+desc.slice(1);
	desc=prompt("Change short description to:", desc1);
    if (!desc) {
        mw.notify("Aborted.");
        return;
     }
	var requestDataS =
	{
		minor: false,
		prependtext: "{{Short description|"+desc+"}}\n",
		summary: (desc===desc1?"Importing Wikidata":"Adding")+" [[Wikipedia:Short description|short description]]: "+desc+" ([[User:1234qwer1234qwer4/shortdescs-in-category.js|shortdescs-in-category]])"
	};
	new mw.Api().edit(page, function() {
		return requestDataS;
	}).done(function(data) {
		
			if (data && data.result && data.result === 'Success')
			{
				mw.notify("Wikidata description imported for "+page);
			}
			else
			{
				alert('There was an error tagging "'+page+'". Code: ' + data);
			}
	}).fail(function(data) {
			alert('There was an error using AJAX to tag "'+page+'". Error: ' + data);
	});
}

function arrayChunk(arr, size) {
	var numChunks = Math.ceil(arr.length / size);
	var result = new Array(numChunks);
	for (var i = 0; i < numChunks; i++) {
		result[i] = arr.slice(i * size, (i + 1) * size);
	}
	return result;
}

// </nowiki>