From 15de93bed3e8412e0eea3e3023b21731fe4af174 Mon Sep 17 00:00:00 2001 From: Diego de la Hera Date: Wed, 21 Aug 2024 13:36:58 -0300 Subject: [PATCH] Use locales provided by us, irrespective of whether they are supported by Zotero or not --- package-lock.json | 29 +++++++++++++++++ package.json | 2 ++ src/utils/locale.ts | 70 +++++++++++++++++++++++++++++++++++++++++ zotero-plugin.config.ts | 19 +++++++++++ 4 files changed, 120 insertions(+) diff --git a/package-lock.json b/package-lock.json index 8892d0d..a00be1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,9 +18,11 @@ "zotero-plugin-toolkit": "^2.3.37" }, "devDependencies": { + "@types/language-tags": "^1.0.4", "@types/node": "^20.10.4", "@types/react-dom": "^18.3.0", "eslint": "^8.55.0", + "language-tags": "^1.0.9", "prettier": "^3.1.1", "typescript": "^5.3.3", "typescript-eslint": "^7.14.1", @@ -1928,6 +1930,13 @@ "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", "dev": true }, + "node_modules/@types/language-tags": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/language-tags/-/language-tags-1.0.4.tgz", + "integrity": "sha512-20PQbifv3v/djCT+KlXybv0KqO5ofoR1qD1wkinN59kfggTPVTWGmPFgL/1yWuDyRcsQP/POvkqK+fnl5nOwTg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/localforage": { "version": "0.0.34", "resolved": "https://registry.npmjs.org/@types/localforage/-/localforage-0.0.34.tgz", @@ -5684,6 +5693,26 @@ "url": "https://github.com/sindresorhus/ky?sponsor=1" } }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/latest-version": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", diff --git a/package.json b/package.json index 3f7f7c2..926711c 100644 --- a/package.json +++ b/package.json @@ -43,9 +43,11 @@ "zotero-plugin-toolkit": "^2.3.37" }, "devDependencies": { + "@types/language-tags": "^1.0.4", "@types/node": "^20.10.4", "@types/react-dom": "^18.3.0", "eslint": "^8.55.0", + "language-tags": "^1.0.9", "prettier": "^3.1.1", "typescript": "^5.3.3", "typescript-eslint": "^7.14.1", diff --git a/src/utils/locale.ts b/src/utils/locale.ts index be9a18e..ae81fc1 100644 --- a/src/utils/locale.ts +++ b/src/utils/locale.ts @@ -20,6 +20,76 @@ function initLocale() { addon.data.locale = { current: l10n, }; + + // Zotero 7 automatically registers Fluent sources for enabled plugins + // found in [plugin-root]/locale/{locale}/ + // See https://www.zotero.org/support/dev/zotero_7_for_developers#registering_fluent_files + // This is handled by function Zotero.Plugins.registerLocales() in + // chrome://zotero/content/xpcom/plugins.js + // However, because of this function's implementation, only exact matches of + // locales supported by Zotero (as listed by + // Services.locale.availableLocales) are registered. This results in, for + // example, our locale "es" not being registered because Zotero supports + // "es-ES" instead. + // The code below removes the source registered by the registerLocales() + // function and replaces it with one that includes all locales supported by + // us. This results in: + // * Our locale "es" will be used even if requested locale is "es-ES", + // * Our locale "pt-BR" will be used even if reqeusted locel is "pt-PT", + // * Locales not supported by Zotero but supported by us (such as kaa) + // will be used if requested, even if the rest of the interface falls + // back to English. + // TODO: Consider moving this code to bootstrap.js. + // TODO: Consider requesting Zotero developers to change the + // registerLocales() function. + + ztoolkit.getGlobal("L10nRegistry").getInstance().removeSources([config.addonID]); + + let source = new (ztoolkit.getGlobal("L10nFileSource"))( + config.addonID, + 'app', + [ + // List of locales supported by us + // TODO: consider picking this up from manifest.json, maybe using + // "l10n_resources" property, as used in Zotero's + // resource://gre/modules/Extension.sys.mjs + "ar", + "ca", + "de", + "en-US", + "es", + "fa", + "fi", + "fr", + "gl", + "he", + "hi", + "id", + "io", + "it", + "kaa", + "ko", + "lt", + "mk", + "nl", + "pms", + "pt-br", + // qqq, + "ro", + "ru", + "sk", + "sl", + "sv", + "tk", + "tr", + "uk", + "zh-hans", + "zh-hant" + ], + rootURI + 'locale/{locale}/' + ); + + ztoolkit.getGlobal("L10nRegistry").getInstance().registerSources([source]); } /** diff --git a/zotero-plugin.config.ts b/zotero-plugin.config.ts index 5d889a1..2320c1b 100644 --- a/zotero-plugin.config.ts +++ b/zotero-plugin.config.ts @@ -5,6 +5,8 @@ import { copyFileSync, readdirSync, renameSync, mkdirSync, cpSync } from "fs"; import fse from "fs-extra"; import { replaceInFileSync } from "zotero-plugin-scaffold/tools"; +import tags from "language-tags"; + export default defineConfig({ source: ["src", "static"], dist: "build", @@ -54,6 +56,23 @@ export default defineConfig({ "build:copyAssets": (ctx) => { const localePath = "build/addon/locale/"; fse.moveSync("build/addon/chrome/locale/", localePath); + + // rename language tags using the correct casing + // otherwise they are ignored by Zotero + for (const dirent of readdirSync( + localePath, { withFileTypes: true } + )) { + if (dirent.isDirectory()) { + const langTag = tags(dirent.name); + if (langTag.valid()) { + renameSync( + localePath + dirent.name, + localePath + langTag.format() + ) + } + } + } + // rename wikicite.properties to addon.ftl for (const path of readdirSync(localePath, { encoding: "utf-8",