From 29fd39a16ef8c9b570bfdbbf7a25f642be442b0e Mon Sep 17 00:00:00 2001
From: Jonas Jenwald <jonas.jenwald@gmail.com>
Date: Wed, 7 Jul 2021 13:53:39 +0200
Subject: [PATCH] [GENERIC viewer] Try to fixup "incomplete" language codes
 (issue 13689)

While I don't know if it's technically correct to even do this, it could provide a slightly better out-of-the-box behaviour in browsers that specify (from the PDF.js `l10n`-folder perspective) "incomplete" language codes.

Rather than immediately falling back to English, we'll use a white-list to try and re-write a "partial" language code to a (hopefully) suitable one that matches an existing `l10n`-folder. The disadvantage of this solution is that the list needs to be kept *manually* up-to-date with any changes in the `l10n`-folder, however new locales are added infrequently enough that this should be acceptable.

Fixes 13689 (assuming we actually want/care to do so, otherwise we should just WONTFIX the issue).
---
 web/genericl10n.js |  4 ++--
 web/l10n_utils.js  | 24 +++++++++++++++++++++++-
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/web/genericl10n.js b/web/genericl10n.js
index 432a84534..2368a3022 100644
--- a/web/genericl10n.js
+++ b/web/genericl10n.js
@@ -14,7 +14,7 @@
  */
 
 import "../external/webL10n/l10n.js";
-import { getL10nFallback } from "./l10n_utils.js";
+import { fixupLangCode, getL10nFallback } from "./l10n_utils.js";
 
 const webL10n = document.webL10n;
 
@@ -22,7 +22,7 @@ class GenericL10n {
   constructor(lang) {
     this._lang = lang;
     this._ready = new Promise((resolve, reject) => {
-      webL10n.setLanguage(lang, () => {
+      webL10n.setLanguage(fixupLangCode(lang), () => {
         resolve(webL10n);
       });
     });
diff --git a/web/l10n_utils.js b/web/l10n_utils.js
index 04e8a549d..8e08cd08c 100644
--- a/web/l10n_utils.js
+++ b/web/l10n_utils.js
@@ -95,6 +95,28 @@ function getL10nFallback(key, args) {
   return DEFAULT_L10N_STRINGS[key] || "";
 }
 
+const PARTIAL_LANG_CODES = {
+  en: "en-US",
+  es: "es-ES",
+  fy: "fy-NL",
+  ga: "ga-IE",
+  gu: "gu-IN",
+  hi: "hi-IN",
+  hy: "hy-AM",
+  nb: "nb-NO",
+  ne: "ne-NP",
+  nn: "nn-NO",
+  pa: "pa-IN",
+  pt: "pt-PT",
+  sv: "sv-SE",
+  zh: "zh-CN",
+};
+
+// Try to support "incompletely" specified language codes (see issue 13689).
+function fixupLangCode(langCode) {
+  return PARTIAL_LANG_CODES[langCode?.toLowerCase()] || langCode;
+}
+
 // Replaces {{arguments}} with their values.
 function formatL10nValue(text, args) {
   if (!args) {
@@ -125,4 +147,4 @@ const NullL10n = {
   async translate(element) {},
 };
 
-export { getL10nFallback, NullL10n };
+export { fixupLangCode, getL10nFallback, NullL10n };