← Files Vibe CodingARCHIVED FILE

assets/catalog/language.js

1.87 KB · Oct 3, 2026 · 06:36 UTC

↓ Download file

function createLanguageManager(onChange) {
  const locales = JSON.parse(document.getElementById('locale-data').textContent);
  const picker = document.getElementById('language');
  const storageKey = 'vibe-coding-language';
  const normalize = value => value === 'zh' ? 'zh-CN' : value;
  const valid = value => Object.prototype.hasOwnProperty.call(locales, value);
  let saved;
  try { saved = localStorage.getItem(storageKey); } catch {}
  const requested = normalize(new URL(location.href).searchParams.get('lang'));
  let language = valid(requested) ? requested : valid(saved) ? saved : 'en';

  function apply() {
    const locale = locales[language];
    document.documentElement.lang = language;
    picker.value = language;
    for (const el of document.querySelectorAll('[data-i18n]')) {
      el.textContent = locale.ui[el.dataset.i18n];
    }
    for (const el of document.querySelectorAll('[data-i18n-aria]')) {
      el.setAttribute('aria-label', locale.ui[el.dataset.i18nAria]);
    }
    for (const el of document.querySelectorAll('[data-i18n-placeholder]')) {
      el.placeholder = locale.ui[el.dataset.i18nPlaceholder];
    }
    for (const link of document.querySelectorAll('[data-local-link]')) {
      const url = new URL(link.href);
      url.searchParams.set('lang', language);
      link.href = url.href;
    }
    onChange(locale, language, locales);
  }

  picker.addEventListener('change', () => {
    if (!valid(picker.value)) return;
    language = picker.value;
    try { localStorage.setItem(storageKey, language); } catch {}
    const url = new URL(location.href);
    url.searchParams.set('lang', language);
    updateCatalogUrl(url);
    apply();
  });
  apply();
}

function formatMessage(template, values) {
  return template.replace(/\{(\w+)\}/g, (match, key) => values[key] ?? match);
}

function updateCatalogUrl(url) {
  try { history.replaceState(null, '', url); } catch {}
}

SHA-256: 194be04d7872cc2516d80c78895458b006dd31d47dd6ff9f2a37eae5855175f8