User:KokoroSenshi/common.js

/** * Autocomplete/Dropdown list * Uses https://yuku-t.com/textcomplete/ * * Notes: * - Won't work with CodeEditor since it doesn't use a textarea but that's fine *  since CodeEditor won't be used for wikitext * - $.getScript is used since mw.loader.load doesn't wait for the code to load *  mw.loader.load('https://unpkg.com/textcomplete@0.13.1/dist/textcomplete.min.js'); * Bugs: * */

if (mw.config.get("wgAction") == 'edit') { /** Global Variables */ strategies = []; // Array of strategies templates = {}; // Contains all the parameter arrays/definitions autoComplete = {}; // Contains supporting variables, e.g. initialismsArray, createTemplateStrategy /** */	templates.Color = {}; $.get( "https://zelda.gamepedia.com/Template:Color?action=raw", function( data ) {		var colorsArray = [];		data.split(" ")[0]			.split("#switch:")[1]			.split("\|#default")[0]			.match(/\|[a-zA-Z0-9 ]*/g)			.forEach(function(value, index){ var name = value.slice(1).trim; colorsArray.push(name); });		templates.Color = {			"1": colorsArray		};	}); templates.KSTest = { "1": ["testparam1value1","testparam1value2","testparam1value3"], "2": ["testparam2value1","testparam2value2","testparam2value3"], "3": ["testparam3value1","testparam3value2","testparam3value3"] };	templates.Icon = {}; $.get( "https://zelda.gamepedia.com/Template:Icon?action=raw", function( data ) {		var iconsArray = [];		data.split(" ")[0]			.split("\|#default")[0]			.match(/\n\|[a-zA-Z0-9-+ ]*/g)			.forEach(function(value, index){ var name = value.slice(2).trim; iconsArray.push(name); });		templates.Icon = {			"1": iconsArray		};	}); autoComplete.initialismsArray = []; var readInitialisms = function(callback) { $.get( "https://zelda.gamepedia.com/Template:Zelda?action=raw", function( data ) {			var initialisms = [];			data.split(" ")[1]				.match(/\|\|[a-zA-Z0-9-+& ]*\n/g)				.forEach(function(value, index){ var name = value.slice(2).trim; initialisms.push(name); });			autoComplete.initialismsArray = initialisms; // Leave autoComplete.initialismsArray empty until fully filled			if (typeof callback === "function") callback;		}); };	/** Initialisms-dependent templates: */ readInitialisms; /* // Won't really need this callback version of the function call? readInitialisms(function {		// Exp Game uses a function, which will get the latest definition of initialismsArray, so isn't needed in this callback	}); */	templates["Exp Game"] = {}; templates["Exp Game"].getParams = function(paramNum) { if (paramNum > 0) // No need to check paramNum, really... return autoComplete.initialismsArray; else return []; };	// Getting a list of every template in the wiki is non-trivial... /* Load Textcomplete then register the strategies */ $(document).ready(getTextcompleteScript); var getTextcompleteScript = function { console.log( "Loading textcomplete..." ); $.getScript( "https://unpkg.com/textcomplete/dist/textcomplete.min.js", function( data, textStatus, jqxhr ) {			console.log( [ data, textStatus, jqxhr.status ] ); // Data returned, Success, 200			console.log( "Loaded textcomplete. (Warning: May not be executed yet)" );			// Textarea object: https://github.com/yuku-t/textcomplete/issues/114#issuecomment-318352383			Textarea = Textcomplete.editors.Textarea; // Global variable			registerStrategies;		}); };	/* Note: The param arrays need ont exist before strategy is registered */ var registerStrategies = function { var editor = new Textarea(document.getElementById('wpTextbox1')) , options = { dropdown: { maxCount: 500, style: { 'margin-top': (-parseFloat($('body').css('margin-top')))+'px' } }			}		, textcomplete = new Textcomplete(editor, options); /** Register strategies */ strategies.push(autoComplete.createTemplateStrategy); textcomplete.register(strategies); };	autoComplete.createTemplateStrategy = function { console.log("createTemplateStrategy start"); var getBeforeCursor = function(textarea) { // Like https://github.com/yuku-t/textcomplete/blob/6f07195c47ace5e787cf7b46604b37a8bd5c6d30/src/textarea.js#L82 if (textarea === null) textarea = document.getElementById('wpTextbox1'); return textarea.selectionStart !== textarea.selectionEnd ? null : textarea.value.substring(0, textarea.selectionEnd); };		var getLastTemplateOpenBracketPos = function(text) { // Assumes no "" (perhaps ok even with these, anyway?), nor tags that would render "" escaped/inactive, var count = 0; var index = text.length-2; while (index >= 0) { var char1 = text.charAt(index); var char2 = text.charAt(index+1); if (char1 === '}' && char2 === '}') { count++; index -= 2; } else if (char1 === '{' && char2 === '{') { count--; index -= 2; } else { index -= 1; }				if (count < 0) return index; }			return -1; };		var templateStrategy = {			id: "Templates", match: /(\|)([^\|]*)$/, search: function (term, callback) { var text = getBeforeCursor; text = text.slice(0, text.length - term.length); //stuff before the term but including the "|" var templateStartPos = getLastTemplateOpenBracketPos(text); var templateName; templateName = text.slice(templateStartPos + "{{".length); //loop regex to remove the templates and tables (there should be no unmatched braces?) OR assume none templateName = templateName.slice(0,text.indexOf("|")); // Count the number of "|" in text to determine which parameter (since it's e.g. "{{templateName|param1|param2|currentparam" ) var paramNum = 0; for (var i=0; i<templateName.length; i++) if (templateName.charAt(i) == '|') paramNum++; var paramArray = []; if (typeof templates[templateName].getParams === "function") { paramArray = templates[templateName].getParams(paramNum); } else { paramArray = templates[templateName][paramNum]; }				var nameArray = paramArray.filter(function(currentValue) { return currentValue.startsWith(term); }); callback(nameArray); // List of possible completions ('names') },			template: function (name) { var displayName = name; return displayName; // What to display in the list },			replace: function (name) { var replacementString = "$1" + name; return replacementString; // What to replace the matched typed text with }		};		console.log("createTemplateStrategy end"); return templateStrategy; }; }