Localized List Automator

Ensuring WCAG 2.2 AA compliance through logical, language-aware ordering.

How the Script Works

To provide a seamless experience for global users, this script performs three primary functions:

  1. Language Detection: It checks the lang attribute of the list itself, falling back to the document language.
  2. Intl.Collator: Instead of a standard sort, it uses the Internationalization API to handle accents (like é vs e) correctly based on the locale.
  3. Translation Awareness: A MutationObserver watches for text changes. If a browser (like Chrome) translates the page, the script detects the new words and instantly re-alphabetizes them.

English List (lang="en")

The following is the English list as coded in the source HTML.

<ul data-sortable="true" class="list-disc ml-6 space-y-2 text-slate-200">
	<li>Zebra</li>
	<li>Apple</li>
	<li>100 Units</li>
	<li>Banana</li>
	<li>20 Units</li>
</ul>

French Section (lang="fr")

Note: "Écureuil" should sort correctly under French rules.

The following is the French list as coded in the source HTML.

<ul lang="fr" data-sortable="true" class="list-disc ml-6 space-y-2 text-slate-200">
	<li>Zèbre</li>
	<li>Pomme</li>
	<li>Écureuil</li>
	<li>Abricot</li>
	<li>100 Éléments</li>
</ul>

The Javascript

The following script was generated by Google Gemini with the prompt available in this page's source code.

/** With the support of Google Gemini.
* Orchestrates the sorting of lists based on their locale.
	 */
const SortManager = {

	// Core sorting logic
	sortList(ul) {
		const lang = ul.closest('[lang]')?.getAttribute('lang') || document.documentElement.lang || 'en';
		const items = Array.from(ul.querySelectorAll('li'));

		// Use Intl.Collator for language-sensitive sorting
		// numeric: true ensures "20" comes before "100"
		const collator = new Intl.Collator(lang, { 
			numeric: true, 
			sensitivity: 'base' 
		});

		items.sort((a, b) => collator.compare(a.textContent.trim(), b.textContent.trim()));

		// Re-append items in new order
		items.forEach(item => ul.appendChild(item));
	},

	// Initialize sorting and setup observers
	init() {
		const lists = document.querySelectorAll('ul[data-sortable="true"]');

		lists.forEach(ul => {
			// Initial Sort
			this.sortList(ul);

			// Observe for changes (like Browser Translation)
			const observer = new MutationObserver((mutations) => {
				// Disconnect briefly to prevent infinite loop during re-sorting
				observer.disconnect();
				this.sortList(ul);
				this.observe(observer, ul);
			});

			this.observe(observer, ul);
		});
	},

	observe(observer, element) {
		observer.observe(element, { 
			childList: true, 
			characterData: true, 
			subtree: true 
		});
	}
};

// Run on load
window.addEventListener('DOMContentLoaded', () => SortM