<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-catfixRegrouper.js</id>
	<title>MediaWiki:Gadget-catfixRegrouper.js - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-catfixRegrouper.js"/>
	<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=MediaWiki:Gadget-catfixRegrouper.js&amp;action=history"/>
	<updated>2026-05-28T05:40:50Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://linguifex.com/w/index.php?title=MediaWiki:Gadget-catfixRegrouper.js&amp;diff=475163&amp;oldid=prev</id>
		<title>Sware: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=MediaWiki:Gadget-catfixRegrouper.js&amp;diff=475163&amp;oldid=prev"/>
		<updated>2025-11-04T17:55:23Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 17:55, 4 November 2025&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=MediaWiki:Gadget-catfixRegrouper.js&amp;diff=475162&amp;oldid=prev</id>
		<title>wikt&gt;Surjection at 17:29, 19 December 2024</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=MediaWiki:Gadget-catfixRegrouper.js&amp;diff=475162&amp;oldid=prev"/>
		<updated>2024-12-19T17:29:45Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;// {{documentation}}&lt;br /&gt;
// &amp;lt;nowiki&amp;gt;&lt;br /&gt;
// implicit dependencies : mediawiki.Title, ext.gadget.catfixRegrouper-Data&lt;br /&gt;
/* jshint maxerr:1048576, strict:true, undef:true, latedef:true, esversion:6 */&lt;br /&gt;
/* global $, mw, RegrouperMetadata */&lt;br /&gt;
&lt;br /&gt;
/* data is in [[MediaWiki:Gadget-catfixRegrouper-Data.js]] */&lt;br /&gt;
&lt;br /&gt;
// characters to ignore when looking for the initial in a title.&lt;br /&gt;
// this is embedded inside a RegExp character class&lt;br /&gt;
const REGROUPER_INITIALS = &amp;quot;-&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
function safeUpperCase(text, dottedDotlessI) {&lt;br /&gt;
	if (dottedDotlessI)&lt;br /&gt;
		return text.replace(/i/g, &amp;quot;İ&amp;quot;).toUpperCase();&lt;br /&gt;
	else&lt;br /&gt;
		return text.toUpperCase();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function safeLowerCase(text, dottedDotlessI) {&lt;br /&gt;
	if (dottedDotlessI)&lt;br /&gt;
		return text.replace(/I/g, &amp;quot;ı&amp;quot;).toLowerCase();&lt;br /&gt;
	else&lt;br /&gt;
		return text.toLowerCase();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function titleCase(text, lang, sc) {&lt;br /&gt;
	return safeUpperCase(text.charAt(0), this.dottedDotlessI)&lt;br /&gt;
		 + safeLowerCase(text.substring(1), this.dottedDotlessI);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function defaultGroup(title, lang, sc) {&lt;br /&gt;
	if (title.length &amp;lt; 1) return undefined;&lt;br /&gt;
	const cleaned = title.replace(this._clean_regex, &amp;quot;&amp;quot;);&lt;br /&gt;
	if (this.initials) {&lt;br /&gt;
		const initialMatch = cleaned.match(this._initials_regex);&lt;br /&gt;
		if (initialMatch) {&lt;br /&gt;
			return titleCase(initialMatch[0], lang, sc);&lt;br /&gt;
		}&lt;br /&gt;
		if (!this.initialFallback) return undefined;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	title = cleaned || title;&lt;br /&gt;
	return titleCase(title.charAt(0), lang, sc);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function makeGroup(groupText) {&lt;br /&gt;
	const groupDiv = document.createElement(&amp;quot;div&amp;quot;);&lt;br /&gt;
	groupDiv.className = &amp;quot;mw-category-group&amp;quot;;&lt;br /&gt;
	const groupH3 = document.createElement(&amp;quot;h3&amp;quot;);&lt;br /&gt;
	groupH3.textContent = groupText;&lt;br /&gt;
	groupDiv.append(groupH3);&lt;br /&gt;
	const groupUl = document.createElement(&amp;quot;ul&amp;quot;);&lt;br /&gt;
	groupDiv.append(groupUl);&lt;br /&gt;
	return [groupDiv, groupUl];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function getLiText(el) {&lt;br /&gt;
	const child = $(el).find(&amp;quot;a, span&amp;quot;).first();&lt;br /&gt;
	const rawText = el.textContent || el.innerText;&lt;br /&gt;
	return (child.length &amp;gt; 0 &amp;amp;&amp;amp; child.text()) || rawText;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
jQuery(() =&amp;gt; {&lt;br /&gt;
	&amp;#039;use strict&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
	let catfix;&lt;br /&gt;
&lt;br /&gt;
	// Apply only to pages in the Category namespace&lt;br /&gt;
	// containing an element with the id &amp;quot;catfix&amp;quot;.&lt;br /&gt;
	// Set window.disableCatfixRegrouper to true to prevent this script from running.&lt;br /&gt;
	if (!(!window.disableCatfixRegrouper&lt;br /&gt;
				&amp;amp;&amp;amp; mw.config.get(&amp;#039;wgNamespaceNumber&amp;#039;) === 14&lt;br /&gt;
				&amp;amp;&amp;amp; (catfix = $(&amp;quot;.catfix&amp;quot;)).length))&lt;br /&gt;
		return;&lt;br /&gt;
	catfix = catfix[0];&lt;br /&gt;
	&lt;br /&gt;
	const catfixSpan = catfix.querySelector(&amp;quot;span&amp;quot;);&lt;br /&gt;
	if (!catfixSpan) return;&lt;br /&gt;
		&lt;br /&gt;
	const regrouperMeta = new RegrouperMetadata();&lt;br /&gt;
&lt;br /&gt;
	// Get the language name and script catfix.&lt;br /&gt;
	const langName = decodeURIComponent(catfix.getAttribute(&amp;quot;data-anchor&amp;quot;).replace(/_/g, &amp;quot; &amp;quot;));&lt;br /&gt;
	catfix = catfix.getElementsByTagName(&amp;quot;*&amp;quot;)[0] || document.createElement(&amp;quot;span&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	const lang = catfixSpan.getAttribute(&amp;quot;lang&amp;quot;);&lt;br /&gt;
	const defaultSc = catfixSpan.classList[0] || &amp;quot;None&amp;quot;;&lt;br /&gt;
	const cachedScriptData = {};&lt;br /&gt;
&lt;br /&gt;
	if (!lang)&lt;br /&gt;
		return;&lt;br /&gt;
&lt;br /&gt;
	const UNPREFIXED_NAMESPACES = [&amp;quot;&amp;quot;, &amp;quot;Talk&amp;quot;, &amp;quot;Citations&amp;quot;];&lt;br /&gt;
	const PREFIXED_NAMESPACES = [&amp;quot;Appendix&amp;quot;, &amp;quot;Appendix talk&amp;quot;, &amp;quot;Reconstruction&amp;quot;, &amp;quot;Reconstruction talk&amp;quot;];&lt;br /&gt;
&lt;br /&gt;
	function isEntry(namespaceName, pageName) {&lt;br /&gt;
		// main, Talk, Citations,&lt;br /&gt;
		// Reconstruction/Appendix (Talk) if it starts with language name and &amp;quot;/&amp;quot;&lt;br /&gt;
		return UNPREFIXED_NAMESPACES.indexOf(namespaceName) !== -1&lt;br /&gt;
			|| (PREFIXED_NAMESPACES.indexOf(namespaceName) !== -1&lt;br /&gt;
				&amp;amp;&amp;amp; pageName.slice(0, langName.length + 1) === langName + &amp;quot;/&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	const formattedNamespaces = mw.config.get(&amp;quot;wgFormattedNamespaces&amp;quot;);&lt;br /&gt;
	const regrouperData = regrouperMeta.getByLang(lang);&lt;br /&gt;
	if (!regrouperData) return;&lt;br /&gt;
&lt;br /&gt;
	// set up stuff for the default regrouper&lt;br /&gt;
	regrouperData._clean_regex = new RegExp(&amp;quot;^[&amp;quot; + ((regrouperData.ignoreAdd || &amp;quot;&amp;quot;) + (regrouperData.ignore || REGROUPER_INITIALS)) + &amp;quot;]+&amp;quot;);&lt;br /&gt;
	if (regrouperData.initials)&lt;br /&gt;
		regrouperData._initials_regex = new RegExp(&amp;quot;^&amp;quot; + regrouperData.initials.source, regrouperData.initials.flags);&lt;br /&gt;
&lt;br /&gt;
	const groupFunction = regrouperData.group;&lt;br /&gt;
	const detectScriptFunction = regrouperData.detectScript;&lt;br /&gt;
&lt;br /&gt;
	function getGroup(pageTitle, oldGroup) {&lt;br /&gt;
		const titleobj = new mw.Title(pageTitle);&lt;br /&gt;
		const namespaceId = titleobj.getNamespaceId();&lt;br /&gt;
		const namespaceName = formattedNamespaces[namespaceId];&lt;br /&gt;
		const pageName = titleobj.getMainText();&lt;br /&gt;
&lt;br /&gt;
		if (!isEntry(namespaceName, pageName))&lt;br /&gt;
			return oldGroup;&lt;br /&gt;
&lt;br /&gt;
		// verify language prefix if the namespace should have one&lt;br /&gt;
		let formattedTitle = pageName;&lt;br /&gt;
		const langPrefix = langName + &amp;quot;/&amp;quot;;&lt;br /&gt;
		if (PREFIXED_NAMESPACES.indexOf(namespaceName) !== -1) {&lt;br /&gt;
			if (formattedTitle.startsWith(langPrefix)) {&lt;br /&gt;
				formattedTitle = formattedTitle.substring(langPrefix.length);&lt;br /&gt;
			} else {&lt;br /&gt;
				return oldGroup;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// ignore unsupported titles unless the language data requests otherwise&lt;br /&gt;
		if (formattedTitle.startsWith(&amp;quot;Unsupported titles/&amp;quot;) &amp;amp;&amp;amp; !regrouperData.unsupported)&lt;br /&gt;
			return oldGroup;&lt;br /&gt;
&lt;br /&gt;
		// script detection&lt;br /&gt;
		let sc = defaultSc;&lt;br /&gt;
		if (detectScriptFunction)&lt;br /&gt;
			sc = detectScriptFunction.call(regrouperData, formattedTitle, lang, sc, namespaceId) || sc;&lt;br /&gt;
&lt;br /&gt;
		let scData = cachedScriptData[sc];&lt;br /&gt;
		if (!scData)&lt;br /&gt;
			scData = cachedScriptData[sc] = regrouperMeta.getBySc(sc) || {};&lt;br /&gt;
&lt;br /&gt;
		let newGroup = true;&lt;br /&gt;
		// the language group function may return true to fall back&lt;br /&gt;
		if (groupFunction)&lt;br /&gt;
			newGroup = groupFunction.call(regrouperData, formattedTitle, lang, sc, namespaceId);&lt;br /&gt;
		if (newGroup === true &amp;amp;&amp;amp; scData.group)&lt;br /&gt;
			newGroup = scData.group.call(regrouperData, formattedTitle, lang, sc, namespaceId);&lt;br /&gt;
		if (newGroup === true)&lt;br /&gt;
			newGroup = defaultGroup.call(regrouperData, formattedTitle, lang, sc, namespaceId);&lt;br /&gt;
&lt;br /&gt;
		return newGroup || oldGroup;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	const GROUP_QUERY = &amp;quot;#mw-pages &amp;gt; .mw-content-ltr .mw-category-group&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	let regroupOk = true;&lt;br /&gt;
	const regroupData = new Map();&lt;br /&gt;
	// Process each group in the category listing.&lt;br /&gt;
	jQuery(GROUP_QUERY)&lt;br /&gt;
		.each(function () {&lt;br /&gt;
			// Get the existing group.&lt;br /&gt;
			const group = $(this).find(&amp;quot;h3&amp;quot;).first().text();&lt;br /&gt;
			if (!group) {&lt;br /&gt;
				// Failed to get group -- something has gone wrong.&lt;br /&gt;
				regroupOk = false;&lt;br /&gt;
				return;&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			$(this).find(&amp;quot;li&amp;quot;)&lt;br /&gt;
				.each(function () {&lt;br /&gt;
					try {&lt;br /&gt;
						const liText = getLiText(this);&lt;br /&gt;
						const newGroup = getGroup(liText, group);&lt;br /&gt;
						regroupData.set(liText, newGroup);&lt;br /&gt;
					} catch (e) {&lt;br /&gt;
						console.error(e);&lt;br /&gt;
						regroupOk = false;&lt;br /&gt;
					}&lt;br /&gt;
				});&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
	// Find the existing groups, which we will delete.&lt;br /&gt;
	const groups = jQuery(GROUP_QUERY);&lt;br /&gt;
	// Cannot regroup if there are no groups.&lt;br /&gt;
	if (!groups.length) return;&lt;br /&gt;
&lt;br /&gt;
	const parent = groups.first().parent()[0];&lt;br /&gt;
	if (!parent) return;&lt;br /&gt;
	const fragment = document.createDocumentFragment();&lt;br /&gt;
&lt;br /&gt;
	if (regroupOk) {&lt;br /&gt;
		let lastGroup, groupUl;&lt;br /&gt;
		jQuery(GROUP_QUERY + &amp;quot; li&amp;quot;)&lt;br /&gt;
			.each(function () {&lt;br /&gt;
				const liText = getLiText(this);&lt;br /&gt;
				const newGroup = regroupData.get(liText) || &amp;quot;&amp;quot;;&lt;br /&gt;
				if (lastGroup !== newGroup) {&lt;br /&gt;
					const elements = makeGroup(newGroup);&lt;br /&gt;
					const groupDiv = elements[0];&lt;br /&gt;
					fragment.appendChild(groupDiv);&lt;br /&gt;
					groupUl = elements[1];&lt;br /&gt;
					lastGroup = newGroup;&lt;br /&gt;
				}&lt;br /&gt;
				groupUl.appendChild(this);&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
		groups.remove();&lt;br /&gt;
		parent.appendChild(fragment);&lt;br /&gt;
	}&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// &amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>wikt&gt;Surjection</name></author>
	</entry>
</feed>