Procházet zdrojové kódy

fix: select the correct Chinese locale (#1144)

James Read před 7 hodinami
rodič
revize
cc5cdcc3c6

+ 22 - 0
frontend/resources/vue/utils/localeSelection.js

@@ -9,6 +9,28 @@ export function selectBrowserLocale (availableLocales, browserLanguages) {
 
     const parts = lowerCandidate.split('-')
 
+    if (parts[0] === 'zh') {
+      let script
+      try {
+        script = new Intl.Locale(candidate).maximize().script
+      } catch (error) {
+        if (error instanceof RangeError) {
+          continue
+        }
+        throw error
+      }
+      const match = availableLocales.find(locale =>
+        locale.toLowerCase().startsWith('zh-') &&
+        new Intl.Locale(locale).maximize().script === script
+      )
+
+      if (match) {
+        return match
+      }
+
+      continue
+    }
+
     for (let length = parts.length - 1; length > 0; length--) {
       const prefix = `${parts.slice(0, length).join('-')}-`
       const match = availableLocales.find(locale => locale.toLowerCase().startsWith(prefix))

+ 23 - 0
frontend/resources/vue/utils/localeSelection.test.mjs

@@ -17,6 +17,29 @@ test('selectBrowserLocale preserves script subtags during fallback', () => {
   assert.equal(selectBrowserLocale(availableLocales, ['zh-Hant-HK']), 'zh-Hant-TW')
 })
 
+for (const language of ['zh-TW', 'zh-HK', 'zh-MO', 'zh-Hant', 'zh-Hant-CN', 'ZH-tw']) {
+  test(`selectBrowserLocale selects Traditional Chinese for ${language}`, () => {
+    assert.equal(selectBrowserLocale(availableLocales, [language]), 'zh-Hant-TW')
+  })
+}
+
+for (const language of ['zh-CN', 'zh-SG', 'zh-Hans', 'zh-Hans-TW', 'zh']) {
+  test(`selectBrowserLocale selects Simplified Chinese for ${language} regardless of locale order`, () => {
+    assert.equal(selectBrowserLocale([...availableLocales].reverse(), [language]), 'zh-Hans-CN')
+  })
+}
+
+test('selectBrowserLocale skips unavailable Chinese scripts and tries the next browser language', () => {
+  assert.equal(selectBrowserLocale(['en', 'de-DE', 'zh-Hans-CN'], ['zh-TW', 'de-AT']), 'de-DE')
+  assert.equal(selectBrowserLocale(['en', 'zh-Hant-TW'], ['zh-CN']), 'en')
+})
+
 test('selectBrowserLocale uses English when no locale matches', () => {
   assert.equal(selectBrowserLocale(availableLocales, ['fr-FR']), 'en')
 })
+
+test('selectBrowserLocale skips malformed Chinese candidates', () => {
+  assert.equal(selectBrowserLocale(availableLocales, ['zh-', 'zh-TW']), 'zh-Hant-TW')
+  assert.equal(selectBrowserLocale(availableLocales, ['zh-Hant-!', 'de-AT']), 'de-DE')
+  assert.equal(selectBrowserLocale(availableLocales, ['zh-']), 'en')
+})