MediaWiki:Gadget-WikitextAutocompleter.js

From Zelda Wiki, the Zelda encyclopedia
Revision as of 07:11, 22 April 2018 by KokoroSenshi (talk | contribs) (Can't identify/fix the position of the dropdown list, will leave it as this for now)
Jump to navigation Jump to search

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/** 
 * 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:
 * - The regex fails if there is an instance of {{Color| before it in the textarea? tho it's fine in the example webpage
 * - In addition, whenyou start a "{{Color|", then pop over to a different "{{Color|", it'll show dropdown, but append to the first "{{Color|""
 * 
 */

var Strategies = {};
Strategies.Template = {};
Strategies.Template.Color = new TemplateStrategy("Color");

$(document).ready(function() {
	console.log( "Loading textcomplete..." );
	$.getScript( "https://unpkg.com/textcomplete@0.13.1/dist/textcomplete.min.js", function( data, textStatus, jqxhr ) {
		console.log( data ); // Data returned
		console.log( textStatus ); // Success
		console.log( jqxhr.status ); // 200
		console.log( "Loaded textcomplete. (Warning: May not be executed yet)" );
		// (Global) Textarea object: https://github.com/yuku-t/textcomplete/issues/114#issuecomment-318352383
		Textarea = Textcomplete.editors.Textarea;
		Strategies.Template.Color.register();
	});
} );

// Been going over OOP in JavaScript: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain#Example

/**
 * Strategy Object
 */

/**
 * Constructor? (and non-prototype definitions)
 * (instance variables can't be accessed without "this." etc.)
 */
function TemplateStrategy(templateName) {
	var params = {};
	
	this.register = function() {
		ajaxGetParams(processParams);
	};
	
	var ajaxGetParams = function (callback) {
		$.get( "https://zelda.gamepedia.com/Template:Color?action=raw", function( data ) {
			params.color = getColorArray(data);
			callback();
		});
	};
	
	var getColorArray = function (text) {
		var colorArray = [];
		text.split("</includeonly>")[0]
			.split("#switch:{{{1\|}}}")[1]
			.split("\|#default")[0]
			.match(/\|[a-zA-Z0-9 ]*/g)
			.forEach(function(value, index){
				var colorName = value.slice(1);
				colorArray.push(colorName);
			});
		return colorArray;
	};
	
	var processParams = function () {
		console.log("params: ");
		console.log(params);
		if (params.length === 0) throw (this + ": params is empty");
		
		var colorStrategy = {
			id: "Template:" + templateName,
			match: new RegExp("(){{" + templateName + "\\|([a-zA-Z 0-9+\\-\\_\\|}]*)$","m"), //TODO: Need to keep the first capture group for it to work? Is it because term in search is the 2nd capture group?
			search: function (term, callback) {
				var nameArray = params.color.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{{" + templateName + "\|" + name + '}}'; // The replace string before 'name' is the same as the RegExp string
				return replacementString; // What to replace the matched typed text with
			}
		};
		console.log("colorStrategy: ");
		console.log(colorStrategy);
		
		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);
		  
		textcomplete.register([colorStrategy]);
		
	};
}