User:1Veertje/KeyShortcuts.js

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.
/* This script is based on [[MediaWiki:Gadget-KeyShortcuts.js]]
   and adds key shortcuts for a variety of common actions, including:
    * Editing labels and lemmas.
    * Adding new statements, forms and senses.
    * Adding another statement for the same property.
    * Editing or adding a reference to the last saved statement.
    * Adding a statement to the last saved form or sense.
    * Opening the merge dialog.
    * Copying the entity ID.
    * Toggling the display of labels for all languages.

   The shortcut `?` will show a popup dialog with a list of supported shortcuts.

   If you'd like to use it, add the following to your common.js:
   mw.loader.load("//www.wikidata.org/w/index.php?title=User:Nikki/KeyShortcuts.js&action=raw&ctype=text/javascript");
*/

$(function () {
	'use strict';
	if (!mw.config.exists("wbEntityId") && mw.config.get("wgNamespaceNumber") !== 640)
		return;

	var n_laststatement = "";

	var mergeDialog = function () {
		$(window.mergeTool.launchDialog).on("keydown", function (event) {
			if (event.keyCode == 13 && !event.isDefaultPrevented()) {
				$(".oo-ui-processDialog-actions-primary a").each(function () { this.click() });
			}
		});
	},
	addStatement = function () {
		$(".wikibase-statementgrouplistview > .wikibase-addtoolbar").first().find("a").first().click();
	},
	editTerms = function () {
		if (mw.config.get("wgCanonicalNamespace") == "Lexeme") {
			$(".lemma-widget_edit").click();
		} else {
			$(".wikibase-entitytermsview .wikibase-toolbar-button-edit a").last().click();
		}
	},
	addForm = function () {
		$(".wikibase-lexeme-forms-section > .wikibase-addtoolbar").last().find("a").first().click();
	},
	addSense = function () {
		$(".wikibase-lexeme-senses-section > .wikibase-addtoolbar").last().find("a").first().click();
	},
	addWikipedia = function () {
		$(".wikibase-sitelinkgrouplistview .wikibase-toolbar-button-edit a").eq(0).click();
		setTimeout(function () {
			$(".wikibase-sitelinkview-siteid-container").find("input").eq(0).trigger("focus");
		}, 500);
	},
	viewHistory = function () {
		$("a[accesskey='h']")[0].click();
	},
	viewItem = function () {
		$("a[accesskey='c']")[0].click();
	},
	toggleAllLanguages = function () {
		$(".wikibase-entitytermsforlanguagelistview-more a").click();
	},
	toggleTermbox = function () {
		$(".wikibase-entitytermsview-entitytermsforlanguagelistview-toggler").click();
	},
	addSenseStatement = function () {
		$(".wikibase-lexeme-senses-section .wikibase-lexeme-sense")
			.last()
			.find(".wikibase-statementgrouplistview > .wikibase-addtoolbar .wikibase-toolbar-button-add a")
			.click();
	},
	addFormStatement = function () {
		$(".wikibase-lexeme-forms-section .wikibase-lexeme-form")
			.last()
			.find(".wikibase-statementgrouplistview > .wikibase-addtoolbar .wikibase-toolbar-button-add a")
			.click();
	},
	editLastStatement = function () {
		let $st;
		if (typeof n_laststatement !== undefined && n_laststatement !== "")
			$st = $(document.getElementsByClassName("wikibase-statement-" + n_laststatement)[0]);
		else
			$st = $(".wikibase-entityview-main > .wikibase-statementgrouplistview .wikibase-statementview").last();

		if (!$st)
			return;

		$st.find(".wikibase-edittoolbar-container .wikibase-toolbar-button-edit a")
			.click();
	},
	addReference = function () {
		$(document.getElementsByClassName("wikibase-statement-" + n_laststatement)[0])
			.find(".wikibase-statementview-references .wikibase-toolbar-button-add a:first")
			.click();
	},
	addAnotherStatement = function () {
		$(document.getElementsByClassName("wikibase-statement-" + n_laststatement)[0])
			.parents(".wikibase-statementgroupview")
			.find(".wikibase-statementlistview > .wikibase-toolbar-wrapper .wikibase-toolbar-button-add a")
			.click();
	},
	expandReferences = function () {
		// if available from [[User:Nikki/ExpandReferences.js]]
		$("#claims small span a").click();
	},
	selectQid = function () {
		var cname = "wikibase-title-id";
		if (document.body.classList.contains("wb-lexemepage"))
			cname = "wb-lexeme-header_id";
		else if (mw.config.get("wgNamespaceNumber") === 640) // EntitySchema
			cname = "entityschema-title-id";
		var qe = document.getElementsByClassName(cname)[0];
		
		// Move brackets from HTML content to CSS pseudo-selectors
		// This prevents them from being included in the selection
		qe.innerHTML = qe.innerHTML.replace(/[()]/g, "");
		var se = document.head.appendChild(document.createElement("style"));
		se.innerHTML = "." + cname + ":before { content: '(' !important }"
			+ " ." + cname + ":after { content: ')' }";

		var selection = window.getSelection();
		var rangex = document.createRange();
		rangex.selectNodeContents(qe);
		selection.removeAllRanges();
		selection.addRange(rangex);
		
		document.execCommand("copy");
	},
	submitStatement = function () {
		$(".ui-inputextender-extended").closest(".wb-edit.wikibase-statementview").find(".wikibase-toolbar-button-save a").click();
	},
	editFirstSense = function () {
		$(".wikibase-lexeme-sense > .wikibase-edittoolbar-container .wikibase-toolbar-button-edit a").eq(0).click();
	},
	addIPA = function () {
		// if available from [[User:Nikki/LexemeAddIPA.js]]
		$("#addipa").click();
	},
	nameGuzzler = function () {
		// if available from [[User:Jitrixis/nameGuzzler.js]]
		$("#t-nameGuzzler a").click();
	},
	toggleHelp = function () {
		$("#n_keyshortcuts_help").toggle();
	};

	$(this).keydown(function (event) {
		if (
			!event.ctrlKey &&
			!event.altKey &&
			!event.metaKey &&
			($(":focus").length === 0 || $("a:focus").length)
		) {
			switch (event.key) {
				case "a": addStatement(); return false;
				case "e": editLastStatement(); return false;
				case "f": addForm(); return false;
				case "h": viewHistory(); return false;
				case "i": viewItem(); return false;
				case "l": editTerms(); return false;
				case "m": mergeDialog(); return false;
				case "q": selectQid(); return false;
				case "r": addReference(); return false;
				case "s": addSense(); return false;
				case "v": nameGuzzler(); return false;
				case "w": addWikipedia(); return false;
				case "x": toggleAllLanguages(); return false;
				case "X": toggleTermbox(); return false;
				case "z": editFirstSense(); return false;
				case "A": addAnotherStatement(); return false;
				case "F": addFormStatement(); return false;
				case "S": addSenseStatement(); return false;
				case "+": expandReferences(); return false;
				case "@": addIPA(); return false;
				case "?": toggleHelp(); return false;
			}
		} else if (
			$(":focus").length === 1
			&& document.activeElement.classList.contains("ui-suggester-input")
			&& event.key == "Enter"
		) {
			submitStatement();
		}
	});

	mw.hook("wikibase.statement.saved").add(function (qid, s) { n_laststatement = s; });

	var n_keymap = {
		"General": {
			"a": "Add statement",
			"A": "Add another statement",
			"e": "Edit last statement",
			"h": "View history",
			"i": "View item",
			"l": "Edit terms/lemma",
			"m": "Open merge dialog",
			"q": "Select and copy ID",
			"r": "Add reference",
			"v": "Open VIP's labels",
			"w": "Add Wikipedia link",
			"x": "Toggle all/fewer languages",
			"X": "Toggle termbox",
			"+": "Show/hide references",
			"?": "Toggle this help"
		},
		"Lexemes": {
			"f": "Add form",
			"F": "Add form statement",
			"s": "Add sense",
			"S": "Add sense statement",
			"@": "Add IPA"
		}
	};

	var module_key_css = // see Module:key
		"border: 1px solid #aaa; border-radius: 0.2em; box-shadow: 0.1em 0.1em 0.2em rgba(0, 0, 0, 0.1);"
		+ "background-color: #f9f9f9; background-image: linear-gradient(to bottom, #eee, #f9f9f9, #eee);"
		+ "padding: 0.1em 0.3em; font-size: 0.85em"; 
	var n_help_html = "<div id='n_keyshortcuts_help' style='display: none; width: 220px; z-index: 100;"
		+ "background-color: white; border: 2px solid black; padding: 10px; margin: 150px 50px;"
		+ "position: fixed; top: 0px; right: 0px;'>";
	for (var i in n_keymap) {
		n_help_html = n_help_html + i + "<ul style='list-style: none; padding-left: 0; margin-left: 0.5em;'>";
		for (var j in n_keymap[i]) {
			// hacky way of only showing + if the user is also using the script for expanding/collapsing references
			if (j === "+" && !$("#claims small span a").length)
				continue;
			if (j === "@" && !$("#addipa").length)
				continue;
			if (j === "v" && !$("#t-nameGuzzler").length)
				continue;
			n_help_html = n_help_html + "<li style='margin-bottom: 0.4em'><kbd style='" + module_key_css + "'>" + j + "</kbd> " + n_keymap[i][j] + "</li>";
		}
		n_help_html = n_help_html + "</ul>";
	}
	n_help_html = n_help_html + "</div>";

	$(document.body).append(n_help_html);
});