User:Erutuon/scripts/moduleDocumentation.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.
- The following documentation is located at User:Erutuon/scripts/moduleDocumentation.js/documentation. [edit]
- Useful links: root page • root page’s subpages • links • redirects • your own
Shows language names for the submodules of Module:accel and Module:number list.
Ideas:
- Add language search dropdown to "create new module" textbox.
/* jshint boss: true, eqeqeq: true, esversion: 6, undef: true, unused: true, varstmt: true */
/* globals $, apiWrapper, mw, OO */
// <nowiki>
(function subpageLinkIIFE() {
"use strict";
const subpageLinkSelector = ".mw-prefixindex-list a";
if (!document.querySelector(subpageLinkSelector))
return;
mw.loader.using([
"mediawiki.storage", "mediawiki.Title", "mediawiki.util"
]).done(() => {
const baseText = mw.config.get("wgPageName").match(/^(?:[^\/]+|\/)/)[0].replace(/_/g, " ");
if (!(baseText === "Module:accel" || baseText === "Module:number list")) {
console.info("Wrong page");
return;
}
const baseTitle = mw.Title.newFromText(baseText);
const baseTitleRegExp = new RegExp("^" + mw.util.escapeRegExp(baseTitle.getMainText() + "/") + "?");
function getSubpage(unprefixedPageName) {
return unprefixedPageName.replace(baseTitleRegExp, "");
}
function removeChildren(elem) {
let child;
while (child = elem.firstChild)
elem.removeChild(child);
}
function appendLangNode(elem, languageCodeToName, langCode) {
const langCodeNode = document.createElement("code");
langCodeNode.textContent = langCode;
for (const child of [
document.createTextNode(languageCodeToName[langCode] + " ("),
langCodeNode,
document.createTextNode(")")
])
elem.appendChild(child);
}
// Must match the following (minus the namespace):
// [[Module:number list/data/en]]
// [[Module:accel/en]]
function getLangCode(subpageName) {
const match = subpageName.match(/^(?:data\/)?([a-z]{2,3}(?:-[a-z]{2,3}){0,2})$/);
return match && match[1];
}
function processPrefixIndex(languageCodeToName) {
Array.prototype.forEach.call($(subpageLinkSelector), subpageLink => {
const text = subpageLink.textContent;
const subpage = getSubpage(text);
subpageLink.textContent = subpage;
const langCode = getLangCode(subpage);
if (!languageCodeToName[langCode]) {
if (langCode)
console.info("invalid language code: ", langCode);
else
console.info("no language code in ", subpage);
subpageLink.parentNode.remove(); // Remove list items containing non-language modules.
return;
}
removeChildren(subpageLink);
appendLangNode(subpageLink, languageCodeToName, langCode);
});
}
/*
* Create an object that loads JSON data with a template on demand and
* saves it in localStorage.
* It provides a doWithData option that takes a callback that requires
* the data, and returns a new function that when called, calls the callback,
* supplying the data to it as the first parameter.
*/
function LanguageData(storageKey, template) {
if (!(typeof storageKey === "string" && typeof template === "string"))
throw new TypeError("Expected string");
this.storageKey = storageKey;
this.template = template;
}
LanguageData.prototype = {
get storage() {
return mw.storage.get(this.storageKey);
},
set storage(val) {
if (val === null || val === undefined)
mw.storage.remove(this.storageKey);
else if (typeof val === "object")
mw.storage.set(this.storageKey, val);
else
throw new TypeError("Expected object, null, or undefined");
},
get data() {
return window[this.storageKey];
},
set data(val) {
window[this.storageKey] = val;
},
};
LanguageData.prototype.loadJSON = function loadJSON(JSONData) {
try {
if (JSONData) {
const data = JSON.parse(JSONData);
if (typeof data !== "object")
throw new TypeError("Object expected");
this.data = data;
return true;
}
} catch (error) {
console.error(error);
}
};
LanguageData.prototype.doWithData = function doWithData(callback, thisValue) {
return () => {
if (this.data || this.loadJSON(this.storage)) {
callback.call(thisValue, this.data);
return;
}
$.getScript("//en.wiktionary.org/w/index.php?title=User:Erutuon/scripts/apiWrapper.js&action=raw")
.done(() => {
apiWrapper.expandTemplates(
this.template,
(JSONData) => {
this.storage = JSONData;
if (this.loadJSON(JSONData))
callback.call(thisValue, this.data);
else
console.error("Fail");
});
});
};
};
const codeToCanonical = new LanguageData(
"WiktionaryCodeToName",
"{{#invoke:languages/javascript-interface|AllCodeToCanonical}}"
);
$(codeToCanonical.doWithData(processPrefixIndex));
mw.loader.using("oojs-ui").done(function () {
const $box = $("#create-new input[type=text]");
const popupContent = $("<p>");
const popup = new OO.ui.PopupWidget({
$content: popupContent,
padded: true,
position: 'above',
});
$box.before(popup.$element);
popup.toggle(false); // hidden initially
function langCatLink(langName) {
const pageName = "Category:" + (langName.indexOf("Language") === -1
? langName + " language" : langName);
return $("<a>").attr("href", mw.util.getUrl(pageName)).html(langName);
}
$box.on("input", codeToCanonical.doWithData(function (codeToName) {
if (this.val() === "" || codeToName[this.val()]) {
this.css({
"background-color": "",
"color": "",
"border-color": "",
});
if (this.val() !== "") {
popupContent.html("language code for ");
popupContent.append(langCatLink(codeToName[this.val()]));
popup.toggle(true);
} else
popup.toggle(false);
} else {
popup.toggle(false);
this.css({
"background-color": "pink",
"color": "red",
"border-color": "red",
});
}
}, $box));
$box.trigger("input");
// const enterKey = 0x0D;
const $form = $box.closest("form");
codeToCanonical.doWithData(function (codeToName) {
$form.submit(function keydownKeyup(event) {
if (!(codeToName[$box.val()])) {
popupContent.html($box.val() + " isn't a valid language code!");
popup.toggle(true);
return false;
}
});
}, $box)();
});
});
})();
// </nowiki>