Keine Bearbeitungszusammenfassung
Keine Bearbeitungszusammenfassung
Markierung: Zurückgesetzt
Zeile 1: Zeile 1:
/* Eigene Sprachleiste: UI-Sprache + PageTranslation-Ziel umschalten */
/* Eigene Sprachleiste: UI-Sprache + PageTranslation-Ziel umschalten (mit Cache) */
mw.loader.using(['mediawiki.util', 'mediawiki.api'], function () {
mw.loader.using(['mediawiki.util', 'mediawiki.api'], function () {


Zeile 6: Zeile 6:
     try {
     try {
       var prefLang = localStorage.getItem('preferredLang');
       var prefLang = localStorage.getItem('preferredLang');
       var currentLang = mw.config.get('wgUserLanguage');
       var currentLang = (mw.config.get('wgUserLanguage') || '').toLowerCase();


       if (
       if (
         prefLang &&
         prefLang &&
         prefLang.toLowerCase() !== currentLang.toLowerCase() &&
         prefLang.toLowerCase() !== currentLang &&
         !/[?&](?:use|set)lang=/.test(location.search)
         !/[?&](?:use|set)lang=/.test(location.search)
       ) {
       ) {
        // setlang = persistente ULS-Sprache (Cookie/Local)
         var url = new URL(window.location.href);
         var url = new URL(window.location.href);
         url.searchParams.set('uselang', prefLang);
         url.searchParams.set('setlang', prefLang);
         location.replace(url.toString());
         location.replace(url.toString());
         return; // Rest des Codes nicht mehr ausführen
         return; // Rest erst nach Redirect ausführen
       }
       }
     } catch (e) {}
     } catch (e) {}
Zeile 29: Zeile 30:
   ];
   ];


  // Wenn bereits eine Leiste existiert, nichts tun
   if (document.getElementById('custom-langbar')) return;
   if (document.getElementById('custom-langbar')) return;


Zeile 37: Zeile 39:
   var baseTitle = pageName.replace(/\/[a-z]{2}(?:-[a-z]{2})?$/i, '');
   var baseTitle = pageName.replace(/\/[a-z]{2}(?:-[a-z]{2})?$/i, '');


   // Leiste bauen
   // ====== Caching-Setup für die Leiste ======
   var bar = document.createElement('div');
   var CACHE_TTL = 24 * 60 * 60 * 1000; // 24h
   bar.id = 'custom-langbar';
   var cacheKey = 'custom-langbar:' + baseTitle + ':' + LANGS.map(function (l) { return l.code; }).join(',') + ':v2';


   LANGS.forEach(function (lang) {
   function buildHtml() {
    var a = document.createElement('a');
    // Direkt zu /lang springen (oder Special:MyLanguage ohne /lang, wenn du lieber adaptiv willst)
    a.href = '#';
    return '<nav aria-label="Sprachen">' + LANGS.map(function (lang) {
    a.textContent = lang.label;
      var href = mw.util.getUrl(baseTitle + '/' + lang.code);
     a.dataset.code = lang.code;
      return '<a href="' + href + '" data-code="' + lang.code + '">' + lang.label + '</a>';
     }).join(' ') + '</nav>';
  }


    if (userLang === lang.code.toLowerCase()) a.className = 'active-lang';
  function renderBar(container, html) {
    container.innerHTML = html;


     a.addEventListener('click', function (e) {
     // aktive Sprache markieren (falls wir auf /xx sind)
       e.preventDefault();
    var m = mw.config.get('wgPageName').match(/\/([a-z-]+)$/i);
      switchLanguageAndGo(lang.code);
    var current = (m ? m[1] : userLang).toLowerCase();
    container.querySelectorAll('a[data-code]').forEach(function (a) {
       if (a.getAttribute('data-code').toLowerCase() === current) a.classList.add('active-lang');
     });
     });
  }
  // ==========================================


    bar.appendChild(a);
  // Leiste einfügen (unterhalb Header)
   });
   var bar = document.createElement('div');
 
   bar.id = 'custom-langbar';
   // Unter die Minerva-Header-Bar hängen
   var header = document.querySelector('.minerva-header') || document.body;
   var header = document.querySelector('.minerva-header') || document.body;
   header.parentNode.insertBefore(bar, header.nextSibling);
   header.parentNode.insertBefore(bar, header.nextSibling);
  // 1) Aus Cache lesen
  try {
    var cached = JSON.parse(localStorage.getItem(cacheKey) || 'null');
    if (cached && (Date.now() - cached.t) < CACHE_TTL && typeof cached.html === 'string') {
      renderBar(bar, cached.html);
    } else {
      // 2) Neu bauen und cachen
      var html = buildHtml();
      renderBar(bar, html);
      try { localStorage.setItem(cacheKey, JSON.stringify({ t: Date.now(), html: html })); } catch (e) {}
    }
  } catch (e) {
    // Fallback ohne Cache
    renderBar(bar, buildHtml());
  }
  // ====== Event-Delegation (funktioniert auch mit gecachtem HTML) ======
  bar.addEventListener('click', function (e) {
    var a = e.target.closest('a[data-code]');
    if (!a) return;
    e.preventDefault();
    switchLanguageAndGo(a.getAttribute('data-code'));
  });
  // =====================================================================


   // ---- Logik: Sprache setzen + auf Übersetzung springen ----
   // ---- Logik: Sprache setzen + auf Übersetzung springen ----
   function targetUrlFor(code) {
   function targetUrlFor(code) {
     // Special:MyLanguage löst auf die passende /lang-Unterseite auf
     // Special:MyLanguage löst auf die passende /lang-Unterseite
     var title = 'Special:MyLanguage/' + baseTitle;
     var title = 'Special:MyLanguage/' + baseTitle;
     var url = mw.util.getUrl(title);
     var url = mw.util.getUrl(title);
    // setlang damit Gäste UND eingeloggte sofort die richtige UI sehen
     var sep = url.indexOf('?') > -1 ? '&' : '?';
     var sep = url.indexOf('?') > -1 ? '&' : '?';
    // setlang sorgt dafür, dass UI+ULS sofort umspringen
     return url + sep + 'setlang=' + encodeURIComponent(code);
     return url + sep + 'setlang=' + encodeURIComponent(code);
   }
   }
Zeile 74: Zeile 107:
     code = code.toLowerCase();
     code = code.toLowerCase();


    // Eingeloggt: Preference setzen, dann auf MyLanguage weiterleiten
     if (mw.config.get('wgUserName')) {
     if (mw.config.get('wgUserName')) {
      // Eingeloggt: Preference per API setzen, dann weiterleiten
       new mw.Api().postWithToken('csrf', {
       new mw.Api().postWithToken('csrf', {
         action: 'options',
         action: 'options',
Zeile 85: Zeile 118:
     }
     }


     // Gäste: direkt mit setlang auf MyLanguage gehen + in localStorage merken
     // Gäste: preferredLang merken und per setlang weiter
     try { localStorage.setItem('preferredLang', code); } catch (e) {}
     try { localStorage.setItem('preferredLang', code); } catch (e) {}
     location.href = targetUrlFor(code);
     location.href = targetUrlFor(code);
Zeile 98: Zeile 131:
   if (!mw.config.get('wgUserName')) {
   if (!mw.config.get('wgUserName')) {
     var ns = mw.config.get('wgNamespaceNumber');
     var ns = mw.config.get('wgNamespaceNumber');
     if (ns % 2 === 1) { // ungerade Namespace-Nummern = Diskussions-Namespace
     if (ns % 2 === 1) { // ungerade Namespace-Nummern = Talk
       var subjectUrl = mw.util.getUrl(mw.config.get('wgPageName').replace(/^Talk:/, ''));
       var subjectUrl = mw.util.getUrl(mw.config.get('wgPageName').replace(/^Talk:/, ''));
       window.location.href = subjectUrl;
       window.location.href = subjectUrl;

Version vom 8. August 2025, 11:56 Uhr

/* Eigene Sprachleiste: UI-Sprache + PageTranslation-Ziel umschalten (mit Cache) */
mw.loader.using(['mediawiki.util', 'mediawiki.api'], function () {

  // ====== Automatische Anwendung der gespeicherten Sprache für Gäste ======
  if (!mw.config.get('wgUserName')) {
    try {
      var prefLang = localStorage.getItem('preferredLang');
      var currentLang = (mw.config.get('wgUserLanguage') || '').toLowerCase();

      if (
        prefLang &&
        prefLang.toLowerCase() !== currentLang &&
        !/[?&](?:use|set)lang=/.test(location.search)
      ) {
        // setlang = persistente ULS-Sprache (Cookie/Local)
        var url = new URL(window.location.href);
        url.searchParams.set('setlang', prefLang);
        location.replace(url.toString());
        return; // Rest erst nach Redirect ausführen
      }
    } catch (e) {}
  }
  // ========================================================================

  // ---- deine Sprachen ----
  var LANGS = [
    { code: 'de', label: 'Deutsch' },
    { code: 'en', label: 'English' },
    { code: 'fr', label: 'Français' }
  ];

  // Wenn bereits eine Leiste existiert, nichts tun
  if (document.getElementById('custom-langbar')) return;

  var userLang = (mw.config.get('wgUserLanguage') || mw.config.get('wgContentLanguage') || 'de').toLowerCase();
  var pageName = mw.config.get('wgPageName');

  // Basis-Seitenname ohne evtl. Sprach-Suffix (/en, /fr, /pt-br, …)
  var baseTitle = pageName.replace(/\/[a-z]{2}(?:-[a-z]{2})?$/i, '');

  // ====== Caching-Setup für die Leiste ======
  var CACHE_TTL = 24 * 60 * 60 * 1000; // 24h
  var cacheKey = 'custom-langbar:' + baseTitle + ':' + LANGS.map(function (l) { return l.code; }).join(',') + ':v2';

  function buildHtml() {
    // Direkt zu /lang springen (oder Special:MyLanguage ohne /lang, wenn du lieber adaptiv willst)
    return '<nav aria-label="Sprachen">' + LANGS.map(function (lang) {
      var href = mw.util.getUrl(baseTitle + '/' + lang.code);
      return '<a href="' + href + '" data-code="' + lang.code + '">' + lang.label + '</a>';
    }).join(' ') + '</nav>';
  }

  function renderBar(container, html) {
    container.innerHTML = html;

    // aktive Sprache markieren (falls wir auf /xx sind)
    var m = mw.config.get('wgPageName').match(/\/([a-z-]+)$/i);
    var current = (m ? m[1] : userLang).toLowerCase();
    container.querySelectorAll('a[data-code]').forEach(function (a) {
      if (a.getAttribute('data-code').toLowerCase() === current) a.classList.add('active-lang');
    });
  }
  // ==========================================

  // Leiste einfügen (unterhalb Header)
  var bar = document.createElement('div');
  bar.id = 'custom-langbar';
  var header = document.querySelector('.minerva-header') || document.body;
  header.parentNode.insertBefore(bar, header.nextSibling);

  // 1) Aus Cache lesen
  try {
    var cached = JSON.parse(localStorage.getItem(cacheKey) || 'null');
    if (cached && (Date.now() - cached.t) < CACHE_TTL && typeof cached.html === 'string') {
      renderBar(bar, cached.html);
    } else {
      // 2) Neu bauen und cachen
      var html = buildHtml();
      renderBar(bar, html);
      try { localStorage.setItem(cacheKey, JSON.stringify({ t: Date.now(), html: html })); } catch (e) {}
    }
  } catch (e) {
    // Fallback ohne Cache
    renderBar(bar, buildHtml());
  }

  // ====== Event-Delegation (funktioniert auch mit gecachtem HTML) ======
  bar.addEventListener('click', function (e) {
    var a = e.target.closest('a[data-code]');
    if (!a) return;
    e.preventDefault();
    switchLanguageAndGo(a.getAttribute('data-code'));
  });
  // =====================================================================

  // ---- Logik: Sprache setzen + auf Übersetzung springen ----
  function targetUrlFor(code) {
    // Special:MyLanguage löst auf die passende /lang-Unterseite
    var title = 'Special:MyLanguage/' + baseTitle;
    var url = mw.util.getUrl(title);
    var sep = url.indexOf('?') > -1 ? '&' : '?';
    // setlang sorgt dafür, dass UI+ULS sofort umspringen
    return url + sep + 'setlang=' + encodeURIComponent(code);
  }

  function switchLanguageAndGo(code) {
    code = code.toLowerCase();

    if (mw.config.get('wgUserName')) {
      // Eingeloggt: Preference per API setzen, dann weiterleiten
      new mw.Api().postWithToken('csrf', {
        action: 'options',
        change: 'language=' + code
      }).always(function () {
        location.href = targetUrlFor(code);
      });
      return;
    }

    // Gäste: preferredLang merken und per setlang weiter
    try { localStorage.setItem('preferredLang', code); } catch (e) {}
    location.href = targetUrlFor(code);
  }

  // Anonyme erkennen und Flag auf <html> setzen
  if (!mw.config.get('wgUserName')) {
    document.documentElement.classList.add('bv-anon');
  }

  // Gäste nicht auf Diskussionsseiten lassen → auf Inhaltsseite umleiten
  if (!mw.config.get('wgUserName')) {
    var ns = mw.config.get('wgNamespaceNumber');
    if (ns % 2 === 1) { // ungerade Namespace-Nummern = Talk
      var subjectUrl = mw.util.getUrl(mw.config.get('wgPageName').replace(/^Talk:/, ''));
      window.location.href = subjectUrl;
    }
  }

});