MediaWiki:Gadget-catfixRegrouper.js
Jump to navigation
Jump to search
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 MediaWiki:Gadget-catfixRegrouper.js/documentation. [edit]
- This script is a part of the
catfixRegrouper
gadget (edit definitions)- Description (edit): Corrects category group headings in language-specific categories on by default
- Useful links: subpage list • links • redirects
Fixes subheadings within category lists.
Uses data in MediaWiki:Gadget-catfixRegrouper-Data.js.
// {{documentation}}
// <nowiki>
// implicit dependencies : mediawiki.Title, ext.gadget.catfixRegrouper-Data
/* jshint maxerr:1048576, strict:true, undef:true, latedef:true, es5:true */
/* global $, mw, RegrouperMetadata */
/* data is in [[MediaWiki:Gadget-catfixRegrouper-Data.js]] */
// characters to ignore when looking for the initial in a title.
// this is embedded inside a RegExp character class
var REGROUPER_INITIALS = "-";
function safeUpperCase(text, dottedDotlessI) {
if (dottedDotlessI)
return text.replace(/i/g, "İ").toUpperCase();
else
return text.toUpperCase();
}
function safeLowerCase(text, dottedDotlessI) {
if (dottedDotlessI)
return text.replace(/I/g, "ı").toLowerCase();
else
return text.toLowerCase();
}
function titleCase(text, lang, sc) {
return safeUpperCase(text.charAt(0), this.dottedDotlessI)
+ safeLowerCase(text.substring(1), this.dottedDotlessI);
}
function defaultGroup(title, lang, sc) {
if (title.length < 1) return undefined;
var cleaned = title.replace(this._clean_regex, "");
if (this.initials) {
var initialMatch = cleaned.match(this._initials_regex);
if (initialMatch) {
return titleCase(initialMatch[0], lang, sc);
}
if (!this.initialFallback) return undefined;
}
title = cleaned || title;
return titleCase(title.charAt(0), lang, sc);
}
function makeGroup(groupText) {
var groupDiv = document.createElement("div");
groupDiv.className = "mw-category-group";
var groupH3 = document.createElement("h3");
groupH3.textContent = groupText;
groupDiv.append(groupH3);
var groupUl = document.createElement("ul");
groupDiv.append(groupUl);
return [groupDiv, groupUl];
}
function getLiText(el) {
var child = $(el).find("a, span").first();
var rawText = el.textContent || el.innerText;
return (child.length > 0 && child.text()) || rawText;
}
jQuery(function () {
'use strict';
var catfix;
// Apply only to pages in the Category namespace
// containing an element with the id "catfix".
// Set window.disableCatfixRegrouper to true to prevent this script from running.
if (!(!window.disableCatfixRegrouper
&& mw.config.get('wgNamespaceNumber') == 14
&& (catfix = document.getElementById("catfix"))))
return;
var regrouperMeta = new RegrouperMetadata();
// Get the language name and script catfix.
var langName = catfix.className.split("CATFIX-")[1];
catfix = catfix.getElementsByTagName("*")[0] || document.createElement("span");
var lang = catfix.getAttribute("lang");
var defaultSc = catfix.classList[0] || "None";
var cachedScriptData = {};
if (!lang)
return;
var UNPREFIXED_NAMESPACES = ["", "Talk", "Citations"];
var PREFIXED_NAMESPACES = ["Appendix", "Appendix talk", "Reconstruction", "Reconstruction talk"];
function isEntry(namespaceName, pageName) {
// main, Talk, Citations,
// Reconstruction/Appendix (Talk) if it starts with language name and "/"
return UNPREFIXED_NAMESPACES.indexOf(namespaceName) != -1
|| (PREFIXED_NAMESPACES.indexOf(namespaceName) != -1
&& pageName.slice(0, langName.length + 1) == langName + "/");
}
var formattedNamespaces = mw.config.get("wgFormattedNamespaces");
var regrouperData = regrouperMeta.getByLang(lang);
if (!regrouperData) return;
// set up stuff for the default regrouper
regrouperData._clean_regex = new RegExp("^[" + ((regrouperData.ignoreAdd || "") + (regrouperData.ignore || REGROUPER_INITIALS)) + "]+");
if (regrouperData.initials)
regrouperData._initials_regex = new RegExp("^" + regrouperData.initials.source, regrouperData.initials.flags);
var groupFunction = regrouperData.group;
var detectScriptFunction = regrouperData.detectScript;
function getGroup(pageTitle, oldGroup) {
var titleobj = new mw.Title(pageTitle);
var namespaceId = titleobj.getNamespaceId();
var namespaceName = formattedNamespaces[namespaceId];
var pageName = titleobj.getMainText();
var formattedTitle = pageName;
var sc = defaultSc;
if (!isEntry(namespaceName, pageName))
return oldGroup;
// verify language prefix if the namespace should have one
var langPrefix = langName + "/";
if (PREFIXED_NAMESPACES.indexOf(namespaceName) != -1) {
if (formattedTitle.startsWith(langPrefix)) {
formattedTitle = formattedTitle.substring(langPrefix.length);
} else {
return oldGroup;
}
}
// ignore unsupported titles unless the language data requests otherwise
if (formattedTitle.startsWith("Unsupported titles/") && !regrouperData.unsupported)
return oldGroup;
// script detection
if (detectScriptFunction)
sc = detectScriptFunction.call(regrouperData, formattedTitle, lang, sc, namespaceId) || sc;
var scData = cachedScriptData[sc];
if (!scData)
scData = cachedScriptData[sc] = regrouperMeta.getBySc(sc) || {};
var newGroup;
if (groupFunction)
newGroup = groupFunction.call(regrouperData, formattedTitle, lang, sc, namespaceId);
else if (scData.group)
newGroup = scData.group.call(regrouperData, formattedTitle, lang, sc, namespaceId);
else
newGroup = defaultGroup.call(regrouperData, formattedTitle, lang, sc, namespaceId);
return newGroup || oldGroup;
}
var GROUP_QUERY = "#mw-pages > .mw-content-ltr .mw-category-group";
var regroupOk = true;
var regroupData = new Map();
// Process each group in the category listing.
jQuery(GROUP_QUERY)
.each(function () {
// Get the existing group.
var group = $(this).find("h3").first().text();
if (!group) {
// Failed to get group -- something has gone wrong.
regroupOk = false;
return;
}
$(this).find("li")
.each(function () {
try {
var liText = getLiText(this);
var newGroup = getGroup(liText, group);
regroupData.set(liText, newGroup);
} catch (e) {
console.error(e);
regroupOk = false;
}
});
});
// Find the existing groups, which we will delete.
var groups = jQuery(GROUP_QUERY);
// Cannot regroup if there are no groups.
if (!groups.length) return;
var parent = groups.first().parent()[0];
if (!parent) return;
var fragment = document.createDocumentFragment();
if (regroupOk) {
var lastGroup, groupUl;
jQuery(GROUP_QUERY + " li")
.each(function () {
var liText = getLiText(this);
var newGroup = regroupData.get(liText) || "";
if (lastGroup != newGroup) {
var elements = makeGroup(newGroup);
var groupDiv = elements[0];
fragment.appendChild(groupDiv);
groupUl = elements[1];
lastGroup = newGroup;
}
groupUl.appendChild(this);
});
groups.remove();
parent.appendChild(fragment);
}
});
// </nowiki>