User:Guywan/Scripts/InsertShortcuts.js

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.
// [[Category:Wikipedia scripts]]
// <nowiki>
if(typeof(window.us_InsertShortcuts) == 'undefined')
{
	window.us_InsertShortcuts =
	{
		DEBUG: false,
		
		inserts: null,
		
		setup: function()
		{
			// Setup key handler.
			window.addEventListener("keydown", e =>
			{
				if(e.altKey && e.key.match(/\d/g))
				{
					var number = e.key === "0" ? 10 : parseInt(e.key);
					
					if(!this.inserts[number - 1]) return;
					
					this.insert(number - 1);
				}
				else if(e.ctrlKey && (e.key == "i" || e.key == "b"))
				{
					this.insert(e.key);
				}
			});
			
			// Load user's settings.
			var page = `User:${mw.config.get("wgUserName")}/InsertShortcutsSettings.js`;
			var loadFrom = window.us_InsertShortcuts_loadFrom === undefined ? null : `https://${us_InsertShortcuts_loadFrom}.org/w/api.php`;
			this.getWikitext(page, wikitext =>
			{
				if(typeof wikitext === 'string' && wikitext.startsWith("!!REDIRECT"))
				{
					project = wikitext.split(" ")[1];
					this.getWikitext(page, wikitext =>
					{
						//				Remove escaped newlines.	Escape 'comments'.	Split into tags.
	            		this.inserts = wikitext.replace(/\\\n/g, "").replace(/^\/\//gm, "").split("\n");
	            		
					}, null, null, `https://${project}.org/w/api.php`);
				}
				else
				{
	            	//				Remove escaped newlines.	Escape 'comments'.	Split into tags.
	            	this.inserts = wikitext.replace(/\\\n/g, "").replace(/^\/\//gm, "").split("\n");
				}
			}, null, null, loadFrom);
		},
		
		insert: function(id)
		{
			const txtarea = document.getElementById("wpTextbox1");
			var start = txtarea.selectionStart;
			var end = txtarea.selectionEnd;
			
			if(start == end)  // Expand to select nearest 'word'.
			{
				while(txtarea.value.charAt(end).match(/\w/g)) end++;
				while(txtarea.value.charAt(start - 1).match(/\w/g)) start--;
				
				if(this.DEBUG) console.log(txtarea.value.substring(start, end));
			}
			
			var tag;
			if(id == "i") tag = "''_''";
			else if(id == "b") tag = "'''_'''";
			else tag = this.inserts[id];
			
			// Put selected text into the tag.								Replace \n's with actual newlines.
			var result = tag.replace("_",  txtarea.value.substring(start, end)).replace(/\\n/g, "\n");
			
			// Update txtarea.
			txtarea.value = txtarea.value.substring(0, start) + result + txtarea.value.substr(end);
			txtarea.selectionStart = end;
			txtarea.selectionEnd = end;
		},
		
		getWikitext: function(sTitles, fDone, fFail=null, fThen=null, href=null)
		{
			var settings =
			{
				"action": "query",
				"prop": "revisions",
				"rvprop": "content",
				"rvslots": "main",
				"rvlimit": 1,
				"titles": sTitles
			};
			
			var api = href === null ? new mw.Api() : new mw.ForeignApi(href);
			api.get(settings)
			.done(data =>
			{
				var wikitext = [];
				for(var id in data.query.pages)
				{
					var revisions = data.query.pages[id].revisions || [];
					if(revisions.length) wikitext.push(revisions[0].slots.main['*']);
				}
				
				if(wikitext.length == 1)
				{
					fDone(wikitext[0]);
				}
				else
				{
					fDone(wikitext);
				}
			}).fail(fFail).then(fThen);
		}
	};
}

$(() =>
{
	if(mw.config.get("wgAction") != "edit") return;
	
	us_InsertShortcuts.setup();
});
// </nowiki>