Jump to content

User:Jts1882/taxonomybrowser.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Jts1882 (talk | contribs) at 11:24, 22 February 2019 (update to new version developed in my common.js). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
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.
//importScript('User:Jts1882/taxonomybrowser.js');

var nLevels = 3;  // this determines how many levels are show in each iteration
var nListLevels = 3;
var nInteractiveLevels = 1;
var debug = false;
var nRun = 1;
var ntt = true; // enable create new taxonomy template tool

/**
 * This script adds a tool and dialog using code modified from the following tutorial script
 * 
 * Tutorial script: QuickRC ("Quick Recent Changes")
 *
 * A tutorial user script which adds a "Quick changelog" link to the page skin's
 * toolbox, and when clicked it pops up a dialog with up to 25 recent edits.
 *
 * Demonstrates:
 * - Use of the API
 * - Use of jQuery
 * - Use of ResourceLoader and some of the default modules that come with it
 * - Use of localization
 *
 * (Be bold and improve it!)
 *
 * Authors:
 * Erik Moeller, 2011, public domain
 * Brion Vibber, 2012, public domain
 */

messages = {
    'en': {
        'taxonomy-title': 'Taxonomy template browser',
        'taxonomy-greeting': 'Welcome, $1!',
        'taxonomy-intro': 'The following templates are children of this taxon taxonomy template:',
        'taxonomy-link': 'Taxonomy browser',
        'taxonomy-link2': 'Taxonomy (test)',
        'taxonomy-tooltip': 'Get children for particular taxonomy template',
        'ntt-link': 'Create new template',
        'ntt-tooltip': 'Create new taxonomy template'
    }
};

mw.messages.set(messages.en);
var lang = mw.config.get('wgUserLanguage');
if (lang && lang != 'en' && lang in messages) {
    mw.messages.set(messages[lang]);
}

// Import the jQuery dialog plugin before starting the rest of this script
mw.loader.using(['jquery.ui.dialog'], function() {

    function openTaxonBrowserDialog( taxon ) {
        taxon = getDefaultTaxonName(taxon);
		var $dialog = $( '<div id="dialog" ></div>' )
			.html( showTaxonomyBrowserForm(taxon)
		//	+ '<div id="output" class="taxonomy-browser" style="align:left">Tree will appear here</div>'
		//	+ showNewTaxonomyTemplateForm(taxon)
			)
			.dialog({
				autoOpen: true,
				title: mw.message('taxonomy-title').plain(),
				width: '60%',
				modal: true
			});
	}
    function openCreateTaxonomyTemplateDialog( taxon ) {
        taxon = getDefaultTaxonName(taxon);
		var $dialog = $( '<div></div>' )
			.html(  showNewTaxonomyTemplateForm(taxon) 	)
			.dialog({
				autoOpen: true,
				title: mw.message('taxonomy-title').plain(),
				width: '60%',
				modal: true
			});
	}
    function renderTaxonomyDialog( output ) {
		var $dialog = $( '<div></div>' )
			.html(
				'<strong>' + mw.message('taxonomy-greeting', mw.user.getName()).escaped() + '</strong> ' 
				+ mw.message('taxonomy-intro').escaped() 
				+ output
			)
			.dialog({
				autoOpen: true,
				title: mw.message('taxonomy-title').plain(),
				width: '60%',
				modal: true
			});
	}
	//------------------------------------ the dialog functions ---------------------------
    function showTaxonomyBrowserForm(taxon) {
    	var text  = "";
		text +=	'<div id="tb" class="taxonomy-browser" style="background-color:#f8f9fa;">'
					+ '<div style="border:1px;padding:0.2em;margin:0.5em;" >'
						+ 'Taxon name:&nbsp;<input id="taxonId" type="text" name="taxonname" style="width:200px;" value="'+taxon+'">'
						//+ 'Levels:    <input id="levelsId" type="text" name="levels" value="1" style="width:50px;">'
						+ '&nbsp;&nbsp;<input id="gettree" type="submit" value="Get taxonomic tree">'
					    //+ '    <button id="gettree2" >Test</button>'
	                + '</div>'
					+ '<div style="float:left;border:1px;padding:0.2em;margin:0.5em;" >'
						+ 'Levels to display:&nbsp;&nbsp; <input id="levelsId" type="text" name="levels" value="1" style="width:20px;text-align:right;">'
	                    + '<br/>Hide extinct taxa:&nbsp;&nbsp;&nbsp;&nbsp; <input id="extinctId" type="checkbox" name="extinct"       value="no" >'
	                    + '<br/>Bold displayed taxa: <input id="bolddisplayId" type="checkbox" name="bolddisplay"       value="no" >'
	                + '</div>'
					+ '<div style="float:left;border:1px solid #dddddd;padding:0.2em;margin:0.5em;">'
						+ 'Output mode: <br/>'
						+ '<input id="mode-list"        type="radio" name="mode"       value="list"   >List'
						+ '<input id="mode-interactive" type="radio" name="mode"       value="interactive"  checked >Interactive'
					+ '</div>'
					+ '<div style="float:left;border:1px solid #dddddd;padding:0.2em;margin:0.5em;">'
						+ 'Show parameters:<br/> '
						+ '<input id="params-show" type="radio" name="parammode" value="show" checked >Yes'
						+ '<input id="params-hide" type="radio" name="parammode" value="hide"         >No'
					+ '</div>'
					+ '<div style="float:left;border:1px solid #dddddd;padding:0.2em;margin:0.5em;visibility:hidden;">'
						+ 'Search type: '
						+ '<input id="search-strict" type="radio" name="searchtype" value="strict" checked >Strict'
						+ '<input id="search-loose"  type="radio" name="searchtype" value="loose"          >Loose'
					+ '</div>'
				+ '</div>' ;
		// add container for tree
		text += '<div id="output" class="taxonomy-browser" style="clear:both;"></div>'; 
		return text;
    }
    function showNewTaxonomyTemplateForm(taxon) {
		return	'<form id="ntt" class="taxonomy-browser">'
				+ 'Taxon name:<input id="ntt-taxon" type="text" name="taxonname" value="'+taxon+'">'
				+ '<button id="nnt-createtemplate" >Create new taxonomy template</button><br/>'
				+ 'Rank:      <input id="ntt-rank" type="text" name="rank" value=""><br/>'
				+ 'Parent:    <input id="ntt-parent" type="text" name="parent" value=""><br/>'
				+ '<fieldset>'
				+ '  Extinct: <input type="checkbox" name="extinct"       value="no" >'
				+ '  Always display: <input type="checkbox" name="alwaysdisplay" value="no" >'
				+ '</fieldset>'
				+ '</form>' ;
       // $('.myCheckbox').prop('checked', true);
    }
    function createNewTemplate (taxon) {
        //taxon = prompt("Enter taxon name for new taxonomy template:", getDefaultTaxonName(taxon));

        var url = 'https://en.wikipedia.org/w/index.php?action=edit&title=Template:taxonomy/'
                   + $('#ntt-taxon').val() 
                   + '&preload=User:Jts1882/Taxonomy/preload'
                   + '&preloadparams%5b%5d=' + $('#ntt-taxon').val()        // link=$1           use taxon 
                   + '&preloadparams%5b%5d=' + $('#ntt-parent').val()       // parent=$2
                   + '&preloadparams%5b%5d=' + $('#ntt-rank').val()         // rank=$3
                   + '&preloadparams%5b%5d=' + ""                // extinct=$4
                   + '&preloadparams%5b%5d=' + ""                // display_always=$5
                   + '&preloadparams%5b%5d=' + ""                // refs=$6
                   + '&preloadparams%5b%5d=' + "";               // same_as=$7
       
        //window.location = url; //"www.example.com/index.php?id=" + this.id;
        window.open(url, 'window name', 'window settings');
        
        
        // target="_blank">
    }
    function getTree(taxon) {
 
        cleanUpAfterPreviousRuns();
		var level = nListLevels;
		
        //taxon = prompt("Enter the parent taxon:", getDefaultTaxonName(taxon));
		taxon =  $('#taxonId').val();
		
		level =$('#levelsId').val();          // can be changed in getTaxonName
        
        var mode = "LIST";
        if ($("#mode-interactive").prop("checked")) {
        	mode = "INTERACTIVE";
        }
        
        
        nInteractiveLevels=level;  // TODO remove multiple level parameters when two methods combined
        
        // top level taxon with empty ul tags
		//var output= '<ul class="taxon_identifier" ><li>' + taxon + '<ul id="' + encodeID(taxon) + '-ul"></ul></li></ul>';
        var output= '<br/><ul><li class="taxon_identifier" id="' + encodeID(taxon) + '-li"><b>' + taxon + '</b></li><br/></ul>';
 		
		$('#output').html(output);
		
		//addChildrenList(taxon, level );  // get data jQuery's AJAX 
		//addChildrenInteractive(taxon, level, "LIST" );
		addChildrenInteractive(taxon, level, mode );
		//renderTaxonomyDialog( output );  // open dialog
        nRun += 1;
    }

	//------------------------------------ the list function ---------------------------
    function getTreeList(taxon) {
 
        cleanUpAfterPreviousRuns();
		var level = nListLevels;
		
        //taxon = prompt("Enter the parent taxon:", getDefaultTaxonName(taxon));
		taxon = getTaxonName(taxon);   // prompt for taxon name
		level =nLevels;         // can be changed in getTaxonName

        // top level taxon with empty ul tags
		var output= '<ul class="taxon_identifier" ><li>' + taxon + '<ul id="' + encodeID(taxon) + '-ul"></ul></li></ul>';
		
		
		addChildrenList(taxon, level );  // get data jQuery's AJAX functions
		renderTaxonomyDialog( output );  // open dialog
        nRun += 1;
    }
    
     // get data jQuery's AJAX functions and create hierarchy tree
    function addChildrenList(taxon, level, callbackfunction) {
       if (level > 0) {
       	    level -= 1;
	 		jQuery.getJSON(
				mw.util.wikiScript( 'api' ),
				{
					'format': 'json',
					'action': 'query',
					'list': 'search',
					'srlimit' : 500,
					'srnamespace' :10,
					'srsearch' : 'insource:"parent[ ]+=[ ]+' + taxon + '" prefix:Template:Taxonomy/'
	
				},
				function( data ) {
	                var output = "";// an empty element with ID exists "<ul><br/>"
	                var nResults = data.query.searchinfo.totalhits;
                    if (nResults === 0) {
                    	//	alert ("zero hits: " + taxon);
                    	output = ' [no children]'; // "zero hits: " + taxon;
                    }
                    else {
						$.each ( data.query.search , function( index , sr ) {
		                     var child =  sr.title.replace("Template:Taxonomy/", "");
	                         var extraInfo = extraText(index , sr);
	                         var rank = getRank(index , sr);
	                         var name = child;
	                         if (rank == "genus") name = '<i>' + child + '</i>';
		                     // href="/wiki/Template:Taxonomy/Machairodontinae">
		                     output += '<li><a href="/wiki/' + sr.title + '">' + name + '</a>'	;
		                     if (debug) output += extraInfo;
		                     //            + ' <button class="childbutton" id="' + child + '">+</button>'
		                     output += '<ul id="' + encodeID(child) + '-ul"></ul>'
		                                + '</li>' ;
		                     addChildrenList(child, level );
	                     
		                     
						} ) ;
                    }
	                // insert children taxa
	                if (nResults > 0) {
	                	$('#'+encodeID(taxon)+'-ul').html(output);  
	                }  else {
	                	$('#'+encodeID(taxon)+'-ul').parent().append(' [no children]'); 
	                	//$('#'+encodeID(taxon)+'-ul').parent().append(output); 
	                	$('#'+encodeID(taxon)+'-ul').remove(); 
	                }
				}
			);        
    	}
    	
    }
    
    // ----------------------------- utlity functions -------------------------------
    function escapeSeq(taxon) {
    	// Special Regex Characters: ., +, *, ?, ^, $, (, ), [, ], {, }, |
    	// Only these four characters require escape sequence inside the bracket list: ^, -, ], \.
    	taxon = taxon.replace(" ("," \\("); 
    	taxon = taxon.replace(")","\\)");
    	taxon = taxon.replace("?","\\?");
    	taxon = taxon.replace("/","\\/");
    	return taxon;
    }
    function encodeID(taxon) {
    	//taxon = taxon.replace("/","_X_");
    	//taxon = taxon.replace("(","_Y_");
    	//taxon = taxon.replace(")","_Z_");
    	//taxon = taxon.replace(" ","_S_");
    	//taxon = taxon.replace("?","_Q_");
    	taxon = taxon.replace(/\//g, "_X_");
    	taxon = taxon.replace(/\(/g, "_Y_");
    	taxon = taxon.replace(/\)/g, "_Z_");
    	taxon = taxon.replace(/ /g,  "_S_");
    	taxon = taxon.replace(/\?/g, "_Q_");
    	taxon = taxon.replace(/\./g, "_D_");
    	return taxon;
	    //return encodeURIComponent(taxon);
    }
    function decodeID(taxon) {
    	//taxon = taxon.replace("_X_","/");
     	//taxon = taxon.replace("_Y_","(");
   	    //taxon = taxon.replace("_Z_",")");
   	    //taxon = taxon.replace("_S_"," ");
   	    //taxon = taxon.replace("_Q_","?");
    	taxon = taxon.replace(/_X_/g, "/");
     	taxon = taxon.replace(/_Y_/g, "(");
   	    taxon = taxon.replace(/_Z_/g, ")");
   	    taxon = taxon.replace(/_S_/g, " ");
   	    taxon = taxon.replace(/_Q_/g, "?");
   	    taxon = taxon.replace(/_D_/g, ".");
   	    return taxon;
	    //return encodeURIComponent(taxon);
    }    
    function getTaxonName(taxon) {
    	
    	taxon = prompt("Enter the parent taxon:", getDefaultTaxonName(taxon));
    	var split = taxon.split(" ");
        if (split[1]) {
          var number = parseInt(split[1]);
          //if (number != NaN) nLevels = number;
          if (!isNaN(number)) {
          	 nLevels = number;
          	 nInteractiveLevels= number;  // TODO make decision on level parameters
          	 nListLevels= number;
          }
          taxon = split[0];
        }
        return taxon;
    }
    function getDefaultTaxonName(taxon) {         // get default from page name
    	
    	var page = mw.config.get( 'wgPageName' ) ;

    	if (page.includes("Template:Taxonomy/") ) {
    	   var res = page.split("Template:Taxonomy/");	
    	   taxon = res[1];
    	}
    	else  {
    	    var title = new mw.Title ( page );
    	    var ns = title.getNamespaceId();
    	    if ( ns === 0 && !page.includes(" ") ) 	taxon = page;
    	}
    	return taxon;
    }
    function  getParameterString(index , sr) {
		
		var paramString = "parameters: "; //" [extra info] ";

		var snippet =sr.snippet; // this contains the template code
		
		if (snippet.includes("rank")) {
			//var rank = templateData.match(/rank[\s]*=[\s]*[a-zA-Z]*/); //gets "rank%s=%sclassis"
			var rank = snippet.match(/rank[\s]*=[\s]*([a-zA-Z ]*)/);
			//if (rank && rank[0] ) 	extraInfo  = ' ['+rank[0]+']';
			if (rank && rank[0] ) 	paramString  += rank[0];
		}
		if (snippet.includes("parent")) {
			var parent = snippet.match(/parent[\s]*=[\s]*([a-zA-Z_ \/\?]*)/);  
			if (parent && parent[0] ) 	paramString  += ' ' + parent[0];
		}
		if (snippet.includes("link")) {
			var link = snippet.match(/link[\s]*=[\s]*([a-zA-Z\|#\(\)"'&; ]*)/);
			//if (snippet.includes("Ichthyostegalia")) alert(link[0] + '_' + link[1] + '_');
			if (link && link[0] ) 	paramString  += ' ' + link[0];
		}
		if (snippet.includes("extinct")) {
			var extinct = snippet.match(/extinct[\s]*=[\s]*([a-zA-Z ]*)/);
			if (extinct && extinct[0] ) 	paramString  += ' ' + extinct[0];
		}
		if (snippet.includes("always_display")) {
			var extinct = snippet.match(/always_display[\s]*=[\s]*([a-zA-Z ]*)/);
			if (extinct && extinct[0] ) 	paramString  += ' ' + extinct[0];
		}
		if (snippet.includes("same_as") || snippet.includes("same as") ) {
			var sameas = snippet.match(/same[ _]as[\s]*=[\s]*([a-zA-Z]*)/);
			if (sameas && sameas[0] ) 	paramString  += ' ' + sameas[0];
		}
		if (snippet.includes("refs")) {
			var refs = snippet.match(/refs[\s]*=[\s]*([a-zA-Z0-9{}| ]*)/);
			var refText = 'refs=[empty]';
			if (refs && refs[1] ) refText =	'refs=[...]';
			paramString  += ' ' + refText;
		}
		//paramString = paramString.replace(/\"/g, '\\\"'); // " already replaced by &quot; in snippet
		return 'title="' + paramString + '" '; 
    }   
    function  getSameAs(index , sr) {
		var snippet =sr.snippet; // this contains the template code
		if (snippet.includes("same_as") || snippet.includes("same as") ) {
			var sameas = snippet.match(/same[ _]as[\s]*=[\s]*([a-zA-Z]*)/);
			if (sameas && sameas[0] ) 	
				return ' [same_as=<a href="/wiki/Template:Taxonomy/' + sameas[1] + '">' + sameas[1] + '</a>]';
		}
		return false;
    }
    function  getExtinct(index , sr) {
		var snippet =sr.snippet; // this contains the template code
		if (snippet.includes("extinct")) {
			var extinct = snippet.match(/extinct[\s]*=[\s]*([a-zA-Z ]*)/);
			if (extinct && extinct[1] ) {
				var value = extinct[1].toLowerCase();
				if (value=="yes" || value=="true") return true;
			}
		}
		return false;
    }
    function  getAlwaysDisplay(index , sr) {
        
        if (!$("#bolddisplayId").prop("checked")) return false;
        
		var snippet =sr.snippet; // this contains the template code
		if (snippet.includes("always_display")) {
			var alwaysDisplay = snippet.match(/always_display[\s]*=[\s]*([a-zA-Z ]*)/);
			if (alwaysDisplay && alwaysDisplay[1] ) {
				var value = alwaysDisplay[1].toLowerCase();
				if (value=="yes" || value=="true") return true;
			}
		}
		if (snippet.includes("rank")) {
			var rank = snippet.match(/rank[\s]*=[\s]*([a-zA-Z ]*)/);
			if (rank && rank[1] ) {
				var value = rank[1].toLowerCase();
				if (value == 'ordo' || value == 'order' || value == 'classis' || value == 'class'
				    || value == 'kingdom' || value == 'phylum' || value == 'divisio' || value == 'division'
				    || value == 'familia' || value == 'family' || value == 'classis' || value == 'class'
				    ) return true;
			}
		}
		return false;
    }
    function getParent(index , sr) {
		var snippet = sr.snippet; // this contains the template code
		if (snippet.includes("parent")) {

			// snippet contains "<span class=\"searchmatch\">parent=Reptiliomorpha</span>"
            //snippet = snippet.replace("</span>",""); 
			
			var parent = snippet.match(/parent[\s]*=[\s]*([a-zA-Z_ \/\?]*)/);  
			if (parent && parent[1] ) {
				return parent[1];
			}
		}
		return false;
    }
    function  getSnippet(index , sr) {
		var snippet =sr.snippet; // this contains the template code
		snippet = snippet.replace('<span class=\"searchmatch\">', "");
		snippet = snippet.replace("</span>",""); 
		return snippet;
    }
    function  getRank(index , sr) {
		var snippet =sr.snippet; // this contains the template code
		if (snippet.includes("rank")) {
		  var rank = snippet.match(/rank[\s]*=[\s]*([a-zA-Z ]*)/); 
		  if (rank && rank[1] ) 	return rank[1];
		}
	/*	if (snippet.includes("same_as") || snippet.includes("same as") ) {
			var sameas = snippet.match(/same[ _]as[\s]*=[\s]*([a-zA-Z]*)/);
			if (sameas && sameas[0] ) 	return sameas[0];
		}*/
		return false; //"unknown rank";
    }
    function formatByRank(name, rank) {
    	// check for genus and species; inlcude should pick up subgenus, species group, etc
        if ( rank && (rank.includes("genus") || rank.includes("species")) ) {
        	name = '<i>' + name + '</i>';
        }
        return name;
    }
    function cleanUpAfterPreviousRuns() {
        if (nRun > 1) {
        	//if (debug) alert ("run number = "+ nRun);
        	$('.taxon_identifier').remove(); 
        }
	}
    ///-------------------------------  interactive function --------------------------------
    function getTreeInteractive(taxon) {

       cleanUpAfterPreviousRuns();

        //taxon = prompt("Enter the parent taxon:", getDefaultTaxonName(taxon));
        taxon = getTaxonName(taxon);
        
 		var output= '<br/><ul><li class="taxon_identifier" id="' + encodeID(taxon) + '-li"><b>' + taxon + '</b></li><br/></ul>';
 		//var output= '<br/><ul><li class="taxon_identifier" id="' + taxon + '-li"><b>' + taxon + '</b></li><br/></ul>';
		
		var level = nInteractiveLevels; // nLevels is globally set at top
		addChildrenInteractive(taxon, level , "INTERACTIVE");  
		renderTaxonomyDialog( output );
        nRun += 1;
    }
    
    function addChildrenInteractive(taxon, level, mode) {
       if (level == 0) return;
   
   	    level -= 1;
	    // perform search using API with one of jQuery's AJAX functions
	    //var search = 'insource:/parent[ ]*=[ ]*' + escapeSeq(taxon) + '[\\s]*/ prefix:Template:Taxonomy/';

        // strict search using RegEx
	    var search = 'insource:/parent[ ]*=[ ]*' + escapeSeq(taxon) + '[a-zA-Z\\/\\?\\s]*/ prefix:Template:Taxonomy/';
	    if ($("#search-loose").prop("checked")) {
	    	search = 'insource:"parent[ ]+=[ ]+' + escapeSeq(taxon) + '" prefix:Template:Taxonomy/';
	    	alert("loose search");
	    }
	    var showParameters = true;
	    if ($("#params-hide").prop("checked")) showParameters = false;
	    var hideExtinct = false;
	    if ($("#extinctId").prop("checked")) hideExtinct = true;
	     	
	    //TODO Ass [a-zA-Z\/\?\s]*
	    //alert(search);
	    //search ="insource:/parent[ ]*=[ ]*Reptiliomorpha\\/\\?[\\s]*/  prefix:Template:Taxonomy/";
	    
 		jQuery.getJSON(
			mw.util.wikiScript( 'api' ),
			{
				'format': 'json',
				'action': 'query',
				'list': 'search',
				'srnamespace' :10,                        // search in template namespace
				'srlimit' : 500,
			//	'srqiprofile' : 'classic',     
				'srsearch' : search  // uses /regex/

			},
			function( data ) {
                var output = ""; 
                var nResults = data.query.searchinfo.totalhits;
                //alert ("nResults="+nResults);
                var count = 0;
                if (nResults === 0) {
                	output = ' [no children]'; // "zero hits: " + taxon;
                	if (showParameters) $('#'+encodeID(taxon)+'-li').append(output); 
                }
                else { // so we have some results
                    if (debug && showParameters) $('#'+encodeID(taxon)+'-li').append(" [" + nResults + "]"); // number of results; includes variants
                    $('#'+encodeID(taxon)+'-li').append('<ul></ul>');   // add ul element to contain children
                    //output = '<ul>';
					$.each ( data.query.search , function( index , sr ) {
	           
	                    var child = sr.title.replace("Template:Taxonomy/", "");		             
                        var rank = getRank(index , sr);
                        var extinct = getExtinct(index , sr);
                        var parent = getParent(index , sr);
                        var alwaysDisplay = getAlwaysDisplay(index , sr);
                        var sameAs = getSameAs(index , sr);
                        var titleString = ""; // alt text to display on mouse over
                        if (showParameters) {  
                            //titleString = 'title="rank='+rank+'; parent='+parent+'; always_display='+alwaysDisplay+'" '; 
                            titleString = getParameterString(index , sr); 
                        }
                        if (hideExtinct && extinct) return true; // don't show extinct taxa   
                        
                        // the results for Template:Taxonomy/TAXON will also contain variant templates;
                        //   we don't want to include those under base template name
                        if (1==1 && (!parent || parent!=taxon )) {
                        	//alert("parent not matching for child "+child+"\nparent="+parent+"\ntaxon="+taxon); 
                        	parent += " (no match)";
                        	return true; // skip to next in each loop (eqquivalent of continue;)
                        }
                        count += 1; // increment counter for matched parents
	                    
                        var name = formatByRank(child, rank);  // italicise if genus or species rank
                        if (alwaysDisplay) name = '<b>' + name + '</b>';
                          
	                    output = '<li id="' + encodeID(child) + '-li" class="taxon_identifier" >';
	                    if (extinct) output += '†';
	                    output += '<a href="/wiki/' + sr.title + '" ' + titleString + '>' + name + '</a>';
	                    
	                    if (showParameters) {
	                    	if (rank)   output += ' ['+rank+']';
	                    	if (sameAs) output += sameAs;
	                    }
	                    if (debug) {
	                    	//output += extraText(index , sr); 
	                        //output += " [child="+child+"; parent="+parent+"; taxon="+taxon+ "]";
	                    }
	                    if (level === 0 && mode=="INTERACTIVE") {
	                     	//output += ' <button class="childbutton" id="' + encodeID(child) + '">+</button>';
	                     	output += ' <span class="childbutton" id="' + encodeID(child) + '" style="font-size:120%;"> &#8862; </span>'; // +/- in square &#8862;/&#8863; +/-/x in circle &#8853;/&#8854;/&#8855;
	                    }
	                    //output += '<br/><ul id="' + encodeID(child) + '-ul"></ul>';
	                    output += '</li>' ;
	        
	                    $('#'+encodeID(taxon)+'-li > ul').append(output);   // append child li element

           		        if (level === 0 && mode=="INTERACTIVE") {
           		        	$('#'+encodeID(child)).click(function (e) {
								e.preventDefault();
	                            addChildrenInteractive(child, nInteractiveLevels, mode );  // trigger new run
							        $(this).hide();
							});	
           		        }
                     
	                    if (level > 0) addChildrenInteractive(child, level, mode );
					});
					output += '</ul>'; // TODO check if still used/needed
					if (showParameters) {
						$('#'+encodeID(taxon)+'-li > ul').before(" [" + count + "]"); // number of results; excludes variants
					}
			    }
			    
			    
			} // end processing function (data)
		);        
    } // end function addChildrenInteractive()
    
    // ----------------- document ready - add functions to tool menu ------------------
	$(document).ready( function() {
		
       // alert("hello")   // my test that the page is loading
		
		//  mw.util.addPortletLink( portletId, href, text, id, tooltip, accesskey, nextnode );
		// Add a link to the toolbox
		var link = mw.util.addPortletLink(
			'p-tb',
			'#',
			mw.message('taxonomy-link').plain(),
			't-prettylinkwidget',
			mw.message('taxonomy-tooltip').plain(),
			'/'
			//'#t-whatlinkshere'    // this places it at the top of the tools
		);
		if (debug) {
			var link2 = mw.util.addPortletLink('p-tb', '#', mw.message('taxonomy-link2').plain(), 't-prettylinkwidget', mw.message('taxonomy-tooltip').plain());
		}
		if (ntt) {
			var link3 = mw.util.addPortletLink('p-tb', '#', mw.message('ntt-link').plain(), 't-prettylinkwidget', mw.message('ntt-tooltip').plain()	);
		}
		// Create a jQuery object for this link so that we get to use jQuery awesomeness 
		//        like .click() for binding functions to events and methods like e.preventDefault();
		$(link).click( function( e ) {
			e.preventDefault(); // Avoid the browser going to '#'
			//getChildren("Felidae");  // get children for prompted taxon
			//getTreeList("Plantae");  // get more than one level of tree 
			if (nRun >1 ) {
				$('.taxonomy-browser').remove(); // remove previous instances of form and output divs (prevents multiple IDs)
			}
			openTaxonBrowserDialog( "Plantae" );
			$('#gettree').click( function( e ) {
				e.preventDefault();
				getTree("Plantae");
			});
				
		});
		if (debug) {
			$(link2).click( function( e ) {
			e.preventDefault();// Avoid the browser going to '#'
			//getTreeInteractive("Carnivora");  // get more than one level of tree
			getTreeInteractive("Tetrapoda");  // get more than one level of tree
			});
		}
		if (ntt) {
			$(link3).click( function( e ) {
				e.preventDefault();// Avoid the browser going to '#'
				openCreateTaxonomyTemplateDialog( "Miodocus" );
				$('#nnt-createtemplate').click( function( e ) {
					e.preventDefault();
					createNewTemplate("Miodocus");
				});
			});
		}
	});

});