Jump to content

User:Frietjes/templatecompare.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.
/// Template Compare Tool
/// Once installed, go to Special:TemplateCompare and provide a templates

function getTemplateText(title){
	// This function was taken from [[User:Timotheus Canens/massedit.js]]
	var req = new XMLHttpRequest();
	req.open("GET", mw.config.get('wgScriptPath') + "/api.php?action=query&prop=revisions&rvprop=content&format=json&indexpageids=1&titles="+encodeURIComponent(title), false);
	req.send();
	var response = JSON.parse(req.responseText);
	pageid = response.query.pageids[0];
	if (pageid == "-1") {
		return '';
	}
	var pagetext = response.query.pages[pageid].revisions[0]['*'];
	return pagetext;
}
function expandtemplates(text){
	var req = new XMLHttpRequest();
	req.open("GET", mw.config.get('wgScriptPath') + "/api.php?action=parse&contentmodel=wikitext&format=json&text="+encodeURIComponent(text),false);
	req.send();
	var response = JSON.parse(req.responseText);
	var pagetext = response.parse.text['*'];
	return pagetext;
}

function getparams(mytxt, templatename) {
	// This function was taken from [[User:Frietjes/addcheckforunknownparameters.js]]
	var plist = [];
	var mytxt2 = mytxt;
	// Remove {PAGENAME}, {BASEPAGENAME}, ...
	mytxt = mytxt.replace(/\{\{(?:PAGENAME|BASEPAGENAME|FULLPAGENAME|CURRENTYEAR)\}\}/g, '');
	// Remove <nowiki /> and <span />
	mytxt = mytxt.replace(/<(?:span|nowiki)[ ]*\/>/gi, '');
	// Excaped table markup
	mytxt = mytxt.replace(/([\r\n])\{(\{\{)(!\}\})/g, '$1$2($3');
	mytxt = mytxt.replace(/([\r\n]\{\{!)(\}\})\}[\t ]*([\r\n])/g, '$1)$2$3');
	// Replace some braces
	mytxt = mytxt.replace(/([^\{])\{([^\{])/g, '$1&#123;$2');
	mytxt = mytxt.replace(/([^\}])\}([^\}])/g, '$1&#125;$2');
	// Replace some equal signs
	mytxt = mytxt.replace(/(<(?:span|div)[^<>]*)=/gi, '$1&#61;');
	// Remove newlines and tabs which confuse the regexp search
	mytxt = mytxt.replace(/[\s]/gm, ' ');
	// Compress whitespace
	mytxt = mytxt.replace(/[\s][\s]+/gm, ' ');
	// Remove some HTML comments
	mytxt = mytxt.replace(/<!--(?:[^>]|[^-]>|[^-]->)*-->/gm, '');
	// Remove some includeonly tags
	mytxt = mytxt.replace(/<\/?includeonly>/gm, '');
	// Remove some noinclude sections
	mytxt = mytxt.replace(/<noinclude>(?:[^<>]|<\/?[^n][^<>]*>)*<\/noinclude>/gm, '');
	// Compress more whitespace
	mytxt = mytxt.replace(/\|[\s]+/g, '|');
	mytxt = mytxt.replace(/(\{\{[^\{\}\|]*)[\s]+(\||\}\})/g, '$1$2');
	// Add a leading and trailing newline to make pattern matches less complicated
	mytxt = '\n' + mytxt + '\n';
	// Avoid false matches
	mytxt2 = mytxt2.replace(/(\{\{\{[^\{\}\|]*)/g, '$1₳₳');
	mytxt2 = mytxt2.replace(/[\s]+₳/g, '₳');
	
	 // Now start extracting the parameters
	var klist = {}; var loopcount = 0;
	while( (mytxt.search(/[^{}]/gm) >= 0) && (loopcount < 15) ) {
		var p = mytxt.match(/(\{\{\{[^{}\|]*\|?[^\{\}\|=]*\}\}\})/g);
		if( p ) {
			for(var j=0; j<p.length; ++j) {
				p[j] = p[j].replace(/\{\{\{([^{}\|]*)\|?[^\{\}\|=]*\}\}\}/g, '$1');
				p[j] = p[j].replace(/^[\s]+/, '');
				p[j] = p[j].replace(/[\s]+$/, '');
				p[j] = p[j].replace(/([\(\)])/g, '\\$1');
				var r = new RegExp("\\{\\{\\{[\\s]*" + p[j].replace(/\?/g, '\\?') + "\\|?[^\\{\\}\\|=]*\\}\\}\\}", 'g');
				mytxt= mytxt.replace(r, '');
				p[j] = p[j].replace(/\\/g, '');
				if( klist[p[j]] === undefined ) {
					klist[p[j]] = mytxt2.indexOf('{{{' + p[j] + '₳₳');
					plist.push(p[j]);
				}
			}
			// Remove templates, parserfunctions, and other double brace expressions
			mytxt = mytxt.replace(/([^\{])\{\{[^{}]*\}\}/gm, '$1');
			mytxt = mytxt.replace(/\{\{[^{}]*\}\}([^\}])/gm, '$1');
			mytxt = mytxt.replace(/([^\{])\{\{(?:[^{}]|\{\{[^{}]*\}\})*\}\}/gm, '$1');
			mytxt = mytxt.replace(/\{\{(?:[^{}]|\{\{[^{}]*\}\})*\}\}([^\}])/gm, '$1');
			// Remove file links
			mytxt = mytxt.replace(/\[\[(?:File|Image):(?:[^\[\]]|\[\[[^\[\]]*)*\]\]/g, '');
		}
		loopcount++;
	}
	if( mytxt.search(/[\{\}]/gm) >= 0 ) {
		mytxt = mytxt.replace(/([\{\}])/gm, '\n<!-- UNPROCESSED HERE -->$1');
		alert('Did not finish processing '+ templatename + ': ' + mytxt);
	}
	// Sort
  	plist.sort(function (a, b) { return a.toLowerCase().localeCompare(b.toLowerCase()) });
  	
	// Return as an = delimited string
  	return plist.join('=');
}

function doTemplateCompare() {
	document.getElementById("wpTemplateCompareSubmit").disabled = true;
	var templates = document.getElementById("wpTemplateCompareTemplates").value.split("\n");
	var showall = document.getElementById("wpTemplateCompareAll").checked;
	var mergeparams = document.getElementById("wpTemplateMerge").checked;
	if(templates.length > 0) {
		if(templates[0].search(/[^\s]/g) < 0) {
			templates.shift();
		}
	}
	var params = new Array(templates.length);
	var allparams = '';
	var i=0; var j=0;
	for(i=0; i< templates.length; i++) {
		templates[i] = templates[i].replace(/[\u200e\s]*\((?:redirect|transclusion)\)[\u200e\s]*\(links[\t ]*\|[\t ]*edit\)[\u200e\s]*$/, '');
		alert('Processing ' + templates[i]);
		var mytxt = getTemplateText(templates[i]);
		var p = getparams(mytxt);
		if (i > 0) {
			allparams += '=' + p;
		} else {
			allparams = p;
		}
		params[i] = p.split('=');
	}
	// Split into a table
	var allparameters = allparams.split('=');
	// Sort
  	allparameters.sort(function (a, b) { return a.toLowerCase().localeCompare(b.toLowerCase()) });
  	// Remove duplicates
  	allparameters = allparameters.filter( function( item, index, inputArray ) {
			return inputArray.indexOf(item) == index;
		});
	// Merged parameters
	var mparameters = {};
	for (i=0; i< allparameters.length; i++) {
		var key = allparameters[i];
		if (mergeparams) {
			key = key.toLowerCase();
			key = key.replace(/[_ ]/g, '');
		}
		if (key in mparameters) {
			mparameters[key].push(allparameters[i]);
		} else {
			mparameters[key] = [allparameters[i]];
		}
	}
	
  	// Report results
  	document.getElementById("wpTemplateCompareSubmit").value = "Done (" + templates.length + ")";
	alert('Found a total of ' + allparameters.length + ' unique parameters.');

	var cp = '{| class="wikitable sortable"\n|-\n! scope=col | Parameter\n';
	var cphtml = '<table class="wikitable sortable">\n<tr>\n<th scope=col>Parameter</th>\n';
	for(i=0; i< templates.length; i++) {
		cp += '! scope=col | [[' + templates[i] + '|' + templates[i].replace(/^Template:/gi, '') + ']]\n';
		cphtml += '<th scope=col><a href="/w/index.php?title=' + encodeURIComponent(templates[i]) 
			+ '" title="' + templates[i] + '">' + templates[i].replace(/^Template:/gi, '') + '</a></th>';
	}
	for (var key in mparameters) {
		var p = mparameters[key].join('<br>');
		var r = '|-\n! scope=row | ' + p + '\n';
		var rhtml = '<tr>\n<th scope=row>' + p + '</th>\n';
		var hiderow = true;
		for (j=0; j<templates.length; j++) {
			var mpk = mparameters[key];
			var hasparam = false;
			for (k=0; k<mpk.length; k++) {
				if (params[j].indexOf(String(mpk[k])) >= 0) {
					hasparam = true;
				}
			}
			if (hasparam) {
				r += '| {{ya}}\n';
				rhtml += '<td data-sort-value="Yes" style="background:#D2FFD2; text-align:center;" class="table-yes2">Yes</td>\n'
			} else {
				r += '| {{na}}\n';
				rhtml += '<td data-sort-value="No" style="background:#FFD2D2; text-align:center;" class="table-no2">No</td>'
				hiderow = false;
			}
		}
		rhtml += '</tr>\n'
		if (showall || (hiderow === false)) {
			cp += r;
			cphtml += rhtml;
		}
	}
	cp += '|}';
	cphtml += '</table>';
	cp = cphtml + '\n<pre>\n' + cp + '\n</pre>';
	document.getElementById("wpTemplateCompareResultsContainer").innerHTML = cp;
}

function templatecompareform() {
	var bodyContent = 'bodyContent';
	switch (mw.config.get('skin')) {
		case 'modern':
			bodyContent = 'mw_contentholder';
			break;
		case 'cologneblue':
			bodyContent = 'article';
			break;
		case 'vector':
		case 'monobook':
		case 'vector':
		default:
			bodyContent = 'bodyContent';
			break;
	}
	document.getElementsByTagName("h1")[0].textContent = "Template compare tool";
	document.title = "Template compare tool - Wikipedia, the free encyclopedia";
	document.getElementById(bodyContent).innerHTML = '<h3 id="siteSub">From Wikipedia, the free encyclopedia</h3><br /><br />'
		+ '<form id="wpTemplateCompare" name="wpTemplateCompare">'
		+ '<b>If you abuse this tool, it\'s <i>your</i> fault, not mine.</b>'
		+ '<p></p>'
			+ 'Templates to compare (one on each line, with namespace prefix):<br />'
			+ '<textarea tabindex="1" name="wpTemplateCompareTemplates" id="wpTemplateCompareTemplates" rows="3" cols="80"></textarea>'
			+ '<input type="checkbox" name="wpTemplateCompareAll" id="wpTemplateCompareAll"> Show all parameters<br>'
			+ '<input type="checkbox" name="wpTemplateCompareMerge" id="wpTemplateMerge"> Merge similar parameters<br>'
			+ '<input type="button" id="wpTemplateCompareSubmit" name="wpTemplateCompareSubmit" value="Compare" onclick="doTemplateCompare()" />'
		+ '</form>\n'
		+ '<div id="wpTemplateCompareResultsContainer"></div>';
}
if(mw.config.get('wgNamespaceNumber') === -1 && (mw.config.get('wgPageName') === "Special:Templatecompare" || mw.config.get('wgPageName') === "Special:TemplateCompare")
) {
	$.when( $.ready, mw.loader.using(['mediawiki.util'])).done( templatecompareform );
}