User:Erutuon/scripts/gadgets-definition.js
< User:Erutuon | scripts
Note: You may have to bypass your browser’s cache to see the changes. In addition, after saving a sitewide CSS file such as MediaWiki:Common.css, it will take 5-10 minutes before the changes take effect, even if you clear your cache.
- Mozilla / Firefox / Safari: hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Command-R on a Macintosh);
- Konqueror and Chrome: click Reload or press F5;
- Opera: clear the cache in Tools → Preferences;
- Internet Explorer: hold Ctrl while clicking Refresh, or press Ctrl-F5.
- This script lacks a documentation subpage. Please create it.
- Useful links: root page • root page’s subpages • links • redirects • your own
/*
* Adds links to gadget definitions in [[MediaWiki:Gadgets-definition]] and
* prettifies them by adding whitespace.
* Adds anchors to gadget definitions as well as CSS to highlight them when we
* click a link to them.
*
* Can be loaded with the following code:
mw.loader.load("//en.wiktionary.org/w/index.php?title=User:Erutuon/scripts/gadgets-definition.js&action=raw&ctype=text/javascript");
*
*/
/* jshint boss: true, undef: true, unused: true */
/* globals $, mw */
(function gadgetsDefinitionIIFE () {
"use strict";
// Only operate on [[MediaWiki:Gadgets-definition]] when the text is visible.
if (!(mw.config.get("wgCanonicalNamespace") == "MediaWiki"
&& mw.config.get("wgTitle") === "Gadgets-definition"
&& document.querySelector(".mw-parser-output")))
return;
const addSpaces = !window.gadgetsDefinitionWhitespaceUnchanged;
mw.loader.using("mediawiki.util", function () {
// Highlight a gadget's definition when we follow a link to it.
mw.util.addCSS(`.page-MediaWiki_Gadgets-definition li:target {
background: var(--background-color-progressive-subtle, #eaf3ff);
}`);
});
// Technique gleaned from [[w:fr:Utilisateur:Od1n/AddLinksGadgetsDefinition.js]].
// This anchor element is used to generate links and is not attached to the document.
var link = document.createElement("a");
function makeLink(href, text) {
link.href = href;
link.textContent = text;
return link.outerHTML;
}
function makeWikilink(page, text) {
return makeLink(mw.util.getUrl(page), text || page);
}
function linkGadgetSource(sourcePage) {
return makeWikilink("MediaWiki:Gadget-" + sourcePage, sourcePage);
}
function linkGadgetAnchor(gadgetName, text) {
return makeLink("#" + makeGadgetId(gadgetName), text || gadgetName);
}
var gadgetNameRegex = /^(\s*)([\w_-]+)\s*/;
function getGadgetName(innerHTML) {
var match = gadgetNameRegex.exec(innerHTML);
return match ? match[2] : null;
}
function makeGadgetId(gadgetName) {
return "Gadget-" + gadgetName;
}
function processGadgetDefinition(innerHTML) {
return innerHTML
// link gadget name to system message page and add space after it
.replace(gadgetNameRegex,
function (wholeMatch, whitespace, gadgetName) {
return whitespace
+ linkGadgetSource(gadgetName)
+ (addSpaces ? " " : "");
})
.replace(/([\w_\-.]+\.(?:css|js(?:on)?))/g, linkGadgetSource) // link script names
.replace(/(\s*)\|(\s*)/g, addSpaces ? " | " : "$1|$2") // spaces around pipes
/*
* process options
*
* Link dependencies: ext.gadget.name to entry on this page, others to
* [[mw:ResourceLoader/Core modules]] (even though not all have an entry
* there).
*
* Link peers to entry on this page.
*
* Link rights to [[mw:Manual:User_rights#List_of_permissions]]. There
* are unfortunately no anchors for individual rights.
*
* Link skin names to page in Skin namespace on MediaWiki. This uses
* wgAvailableSkins so will probably fail if the skin has a
* MediaWiki:skinname-<name> page in the local wiki.
*/
.replace(/([a-z]+)(\s*)=(\s*)(.+?)(?=\s*[|\]])/g,
function (wholeMatch, key, whitespace1, whitespace2, value) {
function mapValues(transformer) {
return value.replace(/([^,\s](?:[^,]*[^,\s])*)(?=\s*(?:,|$))/g, transformer);
}
var formattedValue = value;
switch (key) {
case "dependencies":
formattedValue = mapValues(function (dependency) {
var gadgetName = /^ext\.gadget\.(.+)$/.exec(dependency);
if (gadgetName)
return linkGadgetAnchor(gadgetName[1], dependency);
else
return makeWikilink("mw:ResourceLoader/Core modules#" + dependency, dependency);
});
break;
case "rights":
key = makeWikilink("mw:Manual:User_rights#List_of_permissions", key);
break;
case "skins": {
var skinNames = mw.config.get('wgAvailableSkins');
if (skinNames) {
formattedValue = mapValues(function (skin) {
return skinNames[skin]
? makeWikilink("mw:Skin:" + skinNames[skin], skin)
: skin;
});
}
break;
}
case "peers":
formattedValue = mapValues(linkGadgetAnchor);
break;
case "namespaces":
const formattedNamespaces = mw.config.get("wgFormattedNamespaces");
formattedValue = mapValues(function(namespaceId) {
const namespaceNumber = parseInt(namespaceId);
if (!isNaN(namespaceNumber)) {
const namespaceName = formattedNamespaces[namespaceNumber];
if (namespaceName != undefined) {
const abbr = document.createElement("abbr");
abbr.title = namespaceName === "" ? "(main)" : namespaceName;
abbr.textContent = namespaceId;
return abbr.outerHTML;
}
}
return namespaceId;
});
break;
case "categories":
formattedValue = mapValues(function(categoryName) {
return makeWikilink("Category:" + categoryName, categoryName);
});
}
if (addSpaces) {
whitespace1 = " ", whitespace2 = " ";
}
return key + whitespace1 + "=" + whitespace2
+ (addSpaces ? formattedValue.replace(/\s*,\s*/g, ", ") : formattedValue);
});
}
$(function () {
var $parserOutput = $(".mw-parser-output");
// :not(.gadgets-validation li) excludes elements under
// class="gadgets-definition" in output of Module:validate_gadgets on other wikis.
// Process gadget definitions in lists.
$parserOutput.find("li:not(.gadgets-validation li)").each(function (i, element) {
// Add id so that gadget definitions can be highlighted when we click a link
// to them.
var gadgetName = getGadgetName(element.innerHTML);
if (gadgetName)
element.id = makeGadgetId(gadgetName);
element.innerHTML = processGadgetDefinition(element.innerHTML);
});
// Process gadget definitions in pre tags.
$parserOutput.find("pre:not(.gadgets-validation pre)").each(function (i, element) {
element.innerHTML = element.innerHTML.replace(/[^\n]+/g, processGadgetDefinition);
});
});
})(); // IIFE