Add German, French, and Spanish localization

Add DE/FR/ES support across Chrome, Edge and Firefox builds: new _locales message files for de, fr, es. Include dayjs locale bundles (de.js, fr.js, es.js) and load them in popup.html. Update i18n.js to register new languages and labels, update oper.js to apply the corresponding dayjs locale (including auto-detection), add language buttons to the popup UI, bump manifest version, and record the change in change.log.
This commit is contained in:
jonny
2026-04-24 18:50:18 +08:00
parent bc0ce222ac
commit 3d995079f4
43 changed files with 2014 additions and 6 deletions
+1
View File
@@ -0,0 +1 @@
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n(require("dayjs")):"function"==typeof define&&define.amd?define(["dayjs"],n):(e="undefined"!=typeof globalThis?globalThis:e||self).dayjs_locale_de=n(e.dayjs)}(this,(function(e){"use strict";function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var t=n(e),a={name:"de",weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),months:"Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sept._Okt._Nov._Dez.".split("_"),weekStart:1,formats:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",m:"einer Minute",mm:"%d Minuten",h:"einer Stunde",hh:"%d Stunden",d:"einem Tag",dd:"%d Tagen",M:"einem Monat",MM:"%d Monaten",y:"einem Jahr",yy:"%d Jahren"},ordinal:function(e){return e+"."}};return t.default.locale(a,null,!0),a}));
+1
View File
@@ -0,0 +1 @@
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n(require("dayjs")):"function"==typeof define&&define.amd?define(["dayjs"],n):(e="undefined"!=typeof globalThis?globalThis:e||self).dayjs_locale_es=n(e.dayjs)}(this,(function(e){"use strict";function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var t=n(e),a={name:"es",weekdays:"domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),weekdaysShort:"dom._lun._mar._mié._jue._vie._sáb.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_sá".split("_"),months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:"ene._feb._mar._abr._may._jun._jul._ago._sept._oct._nov._dic.".split("_"),weekStart:1,formats:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un día",dd:"%d días",M:"un mes",MM:"%d meses",y:"un año",yy:"%d años"},ordinal:function(e){return e+"º"}};return t.default.locale(a,null,!0),a}));
+1
View File
@@ -0,0 +1 @@
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n(require("dayjs")):"function"==typeof define&&define.amd?define(["dayjs"],n):(e="undefined"!=typeof globalThis?globalThis:e||self).dayjs_locale_fr=n(e.dayjs)}(this,(function(e){"use strict";function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var t=n(e),a={name:"fr",weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"di_lu_ma_me_je_ve_sa".split("_"),months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),weekStart:1,formats:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},ordinal:function(e){return e+(1===e?"er":"")}};return t.default.locale(a,null,!0),a}));
+7 -1
View File
@@ -1,6 +1,6 @@
const UI_LANGUAGE_STORAGE_KEY = 'uiLanguage'
const SUPPORTED_UI_LANGUAGES = new Set(['auto', 'en', 'zh_CN', 'ja', 'ko'])
const SUPPORTED_UI_LANGUAGES = new Set(['auto', 'en', 'de', 'fr', 'es', 'zh_CN', 'ja', 'ko'])
function normalizeUiLanguage(value) {
const lang = String(value || 'auto')
@@ -49,6 +49,9 @@ let overrideMessages = null
function getLanguageToggleLabel(lang) {
if (lang === 'en') return 'EN'
if (lang === 'de') return 'DE'
if (lang === 'fr') return 'FR'
if (lang === 'es') return 'ES'
if (lang === 'zh_CN') return '中'
if (lang === 'ja') return '日'
if (lang === 'ko') return '한'
@@ -132,6 +135,9 @@ function applyStaticI18n() {
// Language switcher
setText('langOptionAuto', 'langAuto')
setText('langOptionEn', 'langEnglish')
setText('langOptionDe', 'langGerman')
setText('langOptionFr', 'langFrench')
setText('langOptionEs', 'langSpanish')
setText('langOptionZhCN', 'langChineseSimplified')
setText('langOptionJa', 'langJapanese')
setText('langOptionKo', 'langKorean')
+27
View File
@@ -183,6 +183,21 @@ function msg(key) {
function applyDayjsLocaleByUiLanguage(uiLang) {
const lang = String(uiLang || 'auto')
if (lang === 'de') {
dayjs.locale('de')
return
}
if (lang === 'fr') {
dayjs.locale('fr')
return
}
if (lang === 'es') {
dayjs.locale('es')
return
}
if (lang === 'zh_CN') {
dayjs.locale('zh-cn')
return
@@ -205,6 +220,18 @@ function applyDayjsLocaleByUiLanguage(uiLang) {
// auto: best-effort infer from browser UI language
const ui = String(chrome.i18n.getUILanguage ? chrome.i18n.getUILanguage() : '').toLowerCase()
if (ui.startsWith('de')) {
dayjs.locale('de')
return
}
if (ui.startsWith('fr')) {
dayjs.locale('fr')
return
}
if (ui.startsWith('es')) {
dayjs.locale('es')
return
}
if (ui.startsWith('zh')) {
dayjs.locale('zh-cn')
return