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.

jQuery(document).ready(function($) {



var myContent = document.getElementsByName('wpTextbox1')[0];

// -------------------------------------------------------------------------------- //

var mysummary = "Clean up [[:Category:Pages using duplicate arguments in template calls|duplicate template arguments]] using [[:en:User:Frietjes/findargdups|findargdups]]";

if(typeof findargdupseditsummary == 'string') {mysummary = findargdupseditsummary;}

var morefound = "More duplicates found, fix some and run again!";

if(typeof findargdupsmorefound == 'string') {morefound = findargdupsmorefound;}

var linktext = "Find dups";

if(typeof findargdupslinktext == 'string') {linktext = findargdupslinktext;}

var showresultsbox = 0;

if(typeof findargdupsresultsbox == 'string') { showresultsbox = 1;}

var showalertbox = 1;

if(typeof findargdupsnoalertbox == 'string') { showalertbox = 0; showresultsbox = 1;}

var nonefound = 'No duplicates were found!';

if(typeof findargdupsnonefound == 'string') { nonefound = findargdupsnonefound;}

// -------------------------------------------------------------------------------- //



if(mw.config.get('wgNamespaceNumber') != -1 && myContent) {

	mw.loader.using(['mediawiki.util']).done( function() {

	  var portletlink = mw.util.addPortletLink('p-tb', '#', linktext, 't-fdup');

	  $(portletlink).click(function(e) {

	    e.preventDefault();

	    wpFindDuplicateArgs(0);

	  });

	});

}



// -------------------------------------------------------------------------------- //

function wpAddResultsBox(text, num)

{

	var div = document.getElementById('wpSummaryLabel').parentNode;

	if( div ) {

		if( num < 2 ) {

			if( document.getElementById('FindArgDupsResultsBox') ) {

				document.getElementById('FindArgDupsResultsBox').innerHTML = '';

			} else {

				div.innerHTML = '<div id="FindArgDupsResultsBox"></div>' + div.innerHTML;

			}

		}

		div1 = document.getElementById('FindArgDupsResultsBox');

		if( div1 ) {

		text = text.replace(/</g, '&lt;');

		text = text.replace(/>/g, '&gt;');

		div1.innerHTML = div1.innerHTML + '<div class="FindArgDupsResultsBox" ' +

		  'id="FindArgDupsResultsBox-' + num + '" ' +

		  'style="max-height:5em; overflow:auto; padding:5px; border:#aaa 1px solid; ' +

		  'background-color:cornsilk;">' + text + '</div>' + "\n";

		}

	}

}

function wpClearResultsBox()

{

	var div = document.getElementById('wpSummaryLabel').parentNode;

	if( div ) {

		if( document.getElementById('FindArgDupsResultsBox') ) {

				document.getElementById('FindArgDupsResultsBox').innerHTML = '';

		}

	}

}

// -------------------------------------------------------------------------------- //

function wpFindDuplicateArgs(debugflag)

{

  // Flag used to determine if we have issued an alert popup

  var alertissued=0;

  // Flag used to determine if we've selected one of the problem templates yet

  var selectedone=false;

  // Internal for and while loop variables

  var i=0; var j=0; var loopcount=0;

  // Array used to hold the list of unnested templates

  var tlist = []; 

  // Regular expression which matchs a template arg

  var argexp = new RegExp("\\|[\\s]*([^\\s=\\|\\[\\]\\{\\}][^=\\|\\[\\]\\{\\}]*[^\\s=\\|\\[\\]\\{\\}]|[^\\s=\\|\\[\\]\\{\\}]|)[\\s]*=", "gm");

  

  // Copy the contents of the text window so we can modify it without problems

  var mytxt = myContent.value;

  // Remove some includeonly, noinclude, and onlyinclude tags

  mytxt = mytxt.replace(/<\/?[ ]*(?:includeonly|noinclude|onlyinclude)[ ]*>/gi, '');

  // Remove PAGENAME, BASEPAGENAME, ... nested inside of triple braces

  mytxt = mytxt.replace(/\{\{\{[^\{\}]*\|[ ]*\{\{[A-Z]+\}\}\}\}\}/g, '');

  // Mangle some ref tags

  mytxt = mytxt.replace(/(<ref[^<>=]*name[ ]*)=/gi, '$1&#61;');

  mytxt = mytxt.replace(/(<ref[^<>=]*group[ ]*)=/gi, '$1&#61;');

  // Mangle some math tags

  loopcount = 0;

  while((mytxt.search(/<[\s]*math[^<>]*>[^<>=]*=/gi) >= 0) && (loopcount < 10)) {

  	mytxt = mytxt.replace(/(<[\s]*math[^<>]*>[^<>=]*)=/gi, '$1&#61;');

  	loopcount++;

  }

  // Remove some triple braces and parserfunctions inside of triple braces

  loopcount = 0; 

  while((mytxt.search(/\{\{\{[^\{\}]*\}\}\}/g) >= 0) && (loopcount < 5) ) {

    mytxt = mytxt.replace(/\{\{\{[^\{\}]*\}\}\}/g, '');

    mytxt = mytxt.replace(/\{\{#[a-z]+:[^{}=]*\}\}/gi, '');

    loopcount++;

  }

  // Replace some bare braces with HTML equivalent

  mytxt = mytxt.replace(/([^\{])\{([^\{])/g, '$1&#123;$2');

  mytxt = mytxt.replace(/([^\}])\}([^\}])/g, '$1&#125;$2');

  // Remove newlines and tabs which confuse the regexp search

  mytxt = mytxt.replace(/[\s]/gm, ' ');

  // Compress whitespace

  mytxt = mytxt.replace(/[\s][\s]+/gm, ' ');

  // Remove some nowiki and pre text

  mytxt = mytxt.replace(/<nowiki[^<>]*>(?:<[^\/]|[^<])*<\/nowiki[^<>]*>/gi, '');

  mytxt = mytxt.replace(/<pre[^<>]*>(?:<[^\/]|[^<])*<\/pre[^<>]*>/gi, '');

  // Remove some HTML comments

  mytxt = mytxt.replace(/<!--(?:[^>]|[^\-]>|[^\-]->)*-->/gm, '');

  // Modify some = inside of file/image/wikilinks which cause false positives

  loopcount = 0;

  while((mytxt.search(/\[\[[^\[\]\{\}]*=/gi) >= 0) && (loopcount < 5) ) {

    mytxt = mytxt.replace(/(\[\[[^\[\]\{\}]*)=/gi, '$1&#61;');

    loopcount++;

  }



  // Now start unnesting the templates

  loopcount = 0;

  while( (mytxt.search(/(?:\{\{|\}\})/g) >= 0) && (loopcount < 20) ) {

	// Replace some bare braces with HTML equivalent

    mytxt = mytxt.replace(/([^\{])\{([^\{])/g, '$1&#123;$2');

    mytxt = mytxt.replace(/([^\}])\}([^\}])/g, '$1&#125;$2');

  	// Split into chunks, isolating the unnested templates

    var strlist = mytxt.split(/(\{\{[^\{\}]*\}\})/);

    // Loop through the chunks, removing the unnested templates

    for (i = 0; i < strlist.length; i++) {

      if( strlisti].search(/^\{\{[^\{\}]*\}\}$/) >= 0 ) {

         tlist.push(strlisti]);

         strlisti = '';

      }

    }

    // Join the chunks back together for the next iteration

    mytxt = strlist.join('');

    loopcount++;

  }

  

  // Preprocess some = signs inside of non-citation-templated citations

  for(i=0; i < tlist.length; ++i) {

  	j=0;

  	while( (tlisti].search(/<ref[^<>\/]*>(?:<[^\/]|[^<])*=/gi) >= 0) 

  		&& (j < 50) ) {

  		tlisti = tlisti].replace(/(<ref[^<>\/]*>(?:<[^\/]|[^<])*)=/gi, '$1&#61;');

	}

  }

  // Now find duplicates in the list of unnested templates

  for(i=0; i < tlist.length; ++i) {

    // Add numbers for unnamed parameters

    var unp=0;

    tlisti = tlisti].replace(/(\{\{[\s_]*#invoke[\s ]*:[^{}\|]*)\|([^{}\|=]*\|)/gi, '$1|0=$2');

    while((tlisti].search(/(\{\{(?:[^{}\[\]]|\[\[[^\[\]]*\]\])*?\|)((?:[^{}\[\]=\|]|\[[^\[\]=]*\]|\[\[[^\[\]]*\]\])*(?:\||\}\}))/) >= 0)

          && (unp < 25)) {

      unp++;

      tlisti = tlisti].replace(/(\{\{(?:[^{}\[\]]|\[\[[^\[\]]*\]\])*?\|)((?:[^{}\[\]=\|]|\[[^\[\]=]*\]|\[\[[^\[\]]*\]\])*(?:\||\}\}))/, '$1' + unp + '=$2');

    }

    // Array to hold any found duplicate args (reduce number of alerts)

    var f = [];

    // Split the template into an array of | arg = ... strings

    var p = tlisti].match(argexp);

    if( p ) {

      for(j=0; j < p.length; ++j) {

        pj = pj].replace(argexp, '$1');

      }

      p = p.sort();

      for(j=0; j < p.length - 1; ++j) {

        if( pj == pj+1]) {

          f.push(pj]);

        }

      }

    }

    if(f.length > 0) {

      alertissued = alertissued + 1;

      if(alertissued < 5) {

      	if(!selectedone) {

      		var selectmatch = myContent.value.match(tlisti].replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/\s+/g, '\\s*'));

      		if(selectmatch !== null) {

      			myContent.setSelectionRange(selectmatch.index, selectmatch.index + selectmatch0].length);

      			selectedone = true;

      		}

      	}

        if(showresultsbox > 0) {

        	wpAddResultsBox('Duplicate \"' + f.join('\", \"') + '\" in\n' + tlisti], alertissued);

        }

        if(showalertbox > 0) {

        	alert('\"' + f.join('\", \"') + '\" in\n' + tlisti]);

        }

      } else if(alertissued == 6) {

      	alert(morefound);

      }

    }

  }

  if (alertissued) {

    var editsummary = document.getElementsByName('wpSummary')[0];

    if(typeof editsummary == 'object') {

      if (editsummary.value.indexOf(mysummary) == -1) {

        if (editsummary.value.match(/[^\*\/\s][^\/\s]?\s*$/)) {

          editsummary.value += '; ' + mysummary;

        } else {

          editsummary.value += mysummary;

        }

      }

    }

  	if(selectedone) {

  		setTimeout(function() {myContent.focus();}, 0);

  	}

  } else if(nonefound.trim().length > 0) {

		mw.notify(nonefound);

  } else {

  	if(showresultsbox > 0) { wpClearResultsBox(); }

  }

}

// -------------------------------------------------------------------------------- //



});