update: dtd2ftl
This commit is contained in:
parent
8540d1b4cf
commit
25081bf450
@ -28,7 +28,7 @@ This is a plugin template for [Zotero](https://www.zotero.org/). Plugins using t
|
|||||||
|
|
||||||
📌[Zotero Plugin Template](https://github.com/windingwind/zotero-plugin-template)(This repo)
|
📌[Zotero Plugin Template](https://github.com/windingwind/zotero-plugin-template)(This repo)
|
||||||
|
|
||||||
> 👍You are currently in `bootstrap` extension mode. To use `overlay` mode, plsase switch to `overlay` branch in git.
|
> 👍You are currently in `bootstrap` extension mode. To use `overlay` mode, please switch to `overlay` branch in git.
|
||||||
|
|
||||||
> 👁 Watch this repo so that you can be notified whenever there are fixes & updates.
|
> 👁 Watch this repo so that you can be notified whenever there are fixes & updates.
|
||||||
|
|
||||||
@ -40,6 +40,8 @@ If you are using this repo, I recommended that you put this badge ([![Using Zote
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
|
> ❗The localization system is upgraded (dtd is deprecated and we do not use .properties anymore). Only supports Zotero 7.0.0-beta.12 or higher now. If you want to support Zotero 6, you may need to use `dtd`, `properties`, and `ftl` at the same time.
|
||||||
|
|
||||||
- Event-driven, functional programming, under extensive skeleton;
|
- Event-driven, functional programming, under extensive skeleton;
|
||||||
- Simple and user-friendly, works out-of-the-box.
|
- Simple and user-friendly, works out-of-the-box.
|
||||||
- ⭐[New!]Auto hot reload! Whenever the source code is modified, automatically compile and reload. [See here→](#auto-hot-reload)
|
- ⭐[New!]Auto hot reload! Whenever the source code is modified, automatically compile and reload. [See here→](#auto-hot-reload)
|
||||||
@ -221,7 +223,6 @@ Tired of endless restarting? Forget about it!
|
|||||||
|
|
||||||
When file changes are detected in `src` or `addon`, the plugin will be automatically compiled and reloaded.
|
When file changes are detected in `src` or `addon`, the plugin will be automatically compiled and reloaded.
|
||||||
|
|
||||||
|
|
||||||
<details style="text-indent: 2em">
|
<details style="text-indent: 2em">
|
||||||
<summary>💡 Steps to add this feature to an existing plugin</summary>
|
<summary>💡 Steps to add this feature to an existing plugin</summary>
|
||||||
|
|
||||||
@ -232,8 +233,6 @@ When file changes are detected in `src` or `addon`, the plugin will be automatic
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Debug in Zotero
|
### Debug in Zotero
|
||||||
|
|
||||||
You can also:
|
You can also:
|
||||||
|
@ -1,18 +1,22 @@
|
|||||||
|
<linkset>
|
||||||
|
<html:link rel="localization" href="__addonRef__-preferences.ftl" />
|
||||||
|
</linkset>
|
||||||
<vbox
|
<vbox
|
||||||
id="zotero-prefpane-__addonRef__"
|
id="zotero-prefpane-__addonRef__"
|
||||||
onload="Zotero.__addonInstance__.hooks.onPrefsEvent('load', {window})"
|
onload="Zotero.__addonInstance__.hooks.onPrefsEvent('load', {window})"
|
||||||
>
|
>
|
||||||
<groupbox>
|
<groupbox>
|
||||||
<label><html:h2>&zotero.__addonRef__.pref.title;</html:h2></label>
|
<label><html:h2 data-l10n-id="pref-title"></html:h2></label>
|
||||||
<checkbox
|
<checkbox
|
||||||
id="zotero-prefpane-__addonRef__-enable"
|
id="zotero-prefpane-__addonRef__-enable"
|
||||||
label="&zotero.__addonRef__.pref.enable.label;"
|
|
||||||
preference="extensions.zotero.__addonRef__.enable"
|
preference="extensions.zotero.__addonRef__.enable"
|
||||||
|
data-l10n-id="pref-enable"
|
||||||
/>
|
/>
|
||||||
<hbox>
|
<hbox>
|
||||||
<html:label for="zotero-prefpane-__addonRef__-input"
|
<html:label
|
||||||
>&zotero.__addonRef__.pref.input.label;</html:label
|
for="zotero-prefpane-__addonRef__-input"
|
||||||
>
|
data-l10n-id="pref-input"
|
||||||
|
></html:label>
|
||||||
<html:input
|
<html:input
|
||||||
type="text"
|
type="text"
|
||||||
id="zotero-prefpane-__addonRef__-input"
|
id="zotero-prefpane-__addonRef__-input"
|
||||||
@ -25,7 +29,8 @@
|
|||||||
</groupbox>
|
</groupbox>
|
||||||
</vbox>
|
</vbox>
|
||||||
<vbox>
|
<vbox>
|
||||||
<label
|
<html:label
|
||||||
value="&zotero.__addonRef__.help.version.label; &zotero.__addonRef__.help.releasetime.label;"
|
data-l10n-id="pref-help"
|
||||||
></label>
|
data-l10n-args='{"time": "__buildTime__","name": "__addonName__","version":"__buildVersion__"}'
|
||||||
|
></html:label>
|
||||||
</vbox>
|
</vbox>
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
startup.begin=Addon is loading
|
|
||||||
startup.finish=Addon is ready
|
|
||||||
menuitem.label=Addon Template: Helper Examples
|
|
||||||
menupopup.label=Addon Template: Menupopup
|
|
||||||
menuitem.submenulabel=Addon Template
|
|
||||||
menuitem.filemenulabel=Addon Template: File Menuitem
|
|
||||||
prefs.title=Template
|
|
||||||
prefs.table.title=Title
|
|
||||||
prefs.table.detail=Detail
|
|
||||||
tabpanel.lib.tab.label=Lib Tab
|
|
||||||
tabpanel.reader.tab.label=Reader Tab
|
|
@ -1,7 +0,0 @@
|
|||||||
<!ENTITY zotero.__addonRef__.pref.title "Addon Template Example">
|
|
||||||
<!ENTITY zotero.__addonRef__.itemmenu.test.label "addon template">
|
|
||||||
<!ENTITY zotero.__addonRef__.pref.enable.label "Enable">
|
|
||||||
<!ENTITY zotero.__addonRef__.pref.input.label "Input">
|
|
||||||
|
|
||||||
<!ENTITY zotero.__addonRef__.help.version.label "__addonName__ VERSION __buildVersion__">
|
|
||||||
<!ENTITY zotero.__addonRef__.help.releasetime.label "Build __buildTime__">
|
|
@ -1,11 +0,0 @@
|
|||||||
startup.begin=插件加载中
|
|
||||||
startup.finish=插件已就绪
|
|
||||||
menuitem.label=插件模板: 帮助工具样例
|
|
||||||
menupopup.label=插件模板: 弹出菜单
|
|
||||||
menuitem.submenulabel=插件模板:子菜单
|
|
||||||
menuitem.filemenulabel=插件模板: 文件菜单
|
|
||||||
prefs.title=插件模板
|
|
||||||
prefs.table.title=标题
|
|
||||||
prefs.table.detail=详情
|
|
||||||
tabpanel.lib.tab.label=库标签
|
|
||||||
tabpanel.reader.tab.label=阅读器标签
|
|
@ -1,7 +0,0 @@
|
|||||||
<!ENTITY zotero.__addonRef__.pref.title "插件模板设置示例">
|
|
||||||
<!ENTITY zotero.__addonRef__.itemmenu.test.label "插件模板">
|
|
||||||
<!ENTITY zotero.__addonRef__.pref.enable.label "开启">
|
|
||||||
<!ENTITY zotero.__addonRef__.pref.input.label "输入">
|
|
||||||
|
|
||||||
<!ENTITY zotero.__addonRef__.help.version.label "__addonName__ 版本 __buildVersion__">
|
|
||||||
<!ENTITY zotero.__addonRef__.help.releasetime.label "Build __buildTime__">
|
|
11
addon/locale/en-US/addon.ftl
Normal file
11
addon/locale/en-US/addon.ftl
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
startup-begin = Addon is loading
|
||||||
|
startup-finish = Addon is ready
|
||||||
|
menuitem-label = Addon Template: Helper Examples
|
||||||
|
menupopup-label = Addon Template: Menupopup
|
||||||
|
menuitem-submenulabel = Addon Template
|
||||||
|
menuitem-filemenulabel = Addon Template: File Menuitem
|
||||||
|
prefs-title = Template
|
||||||
|
prefs-table-title = Title
|
||||||
|
prefs-table-detail = Detail
|
||||||
|
tabpanel-lib-tab-label = Lib Tab
|
||||||
|
tabpanel-reader-tab-label = Reader Tab
|
4
addon/locale/en-US/preferences.ftl
Normal file
4
addon/locale/en-US/preferences.ftl
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
pref-title = Addon Template Example
|
||||||
|
pref-enable =
|
||||||
|
.label = Enable
|
||||||
|
pref-help = { $name } Build { $version } { $time }
|
11
addon/locale/zh-CN/addon.ftl
Normal file
11
addon/locale/zh-CN/addon.ftl
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
startup-begin = 插件加载中
|
||||||
|
startup-finish = 插件已就绪
|
||||||
|
menuitem-label = 插件模板: 帮助工具样例
|
||||||
|
menupopup-label = 插件模板: 弹出菜单
|
||||||
|
menuitem-submenulabel = 插件模板:子菜单
|
||||||
|
menuitem-filemenulabel = 插件模板: 文件菜单
|
||||||
|
prefs-title = 插件模板
|
||||||
|
prefs-table-title = 标题
|
||||||
|
prefs-table-detail = 详情
|
||||||
|
tabpanel-lib-tab-label = 库标签
|
||||||
|
tabpanel-reader-tab-label = 阅读器标签
|
5
addon/locale/zh-CN/preferences.ftl
Normal file
5
addon/locale/zh-CN/preferences.ftl
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
pref-title = 插件模板设置示例
|
||||||
|
pref-enable =
|
||||||
|
.label = 开启
|
||||||
|
pref-input = 输入
|
||||||
|
pref-help = { $name } Build { $version } { $time }
|
@ -9,6 +9,7 @@ import {
|
|||||||
mkdirSync,
|
mkdirSync,
|
||||||
readdirSync,
|
readdirSync,
|
||||||
rmSync,
|
rmSync,
|
||||||
|
renameSync,
|
||||||
} from "fs";
|
} from "fs";
|
||||||
import { env, exit } from "process";
|
import { env, exit } from "process";
|
||||||
import replaceInFile from "replace-in-file";
|
import replaceInFile from "replace-in-file";
|
||||||
@ -158,6 +159,30 @@ async function main() {
|
|||||||
|
|
||||||
console.log("[Build] Replace OK");
|
console.log("[Build] Replace OK");
|
||||||
|
|
||||||
|
// Walk the builds/addon/locale folder's sub folders and rename *.ftl to addonRef-*.ftl
|
||||||
|
const localeDir = join(buildDir, "addon/locale");
|
||||||
|
const localeFolders = readdirSync(localeDir, { withFileTypes: true })
|
||||||
|
.filter((dirent) => dirent.isDirectory())
|
||||||
|
.map((dirent) => dirent.name);
|
||||||
|
|
||||||
|
for (const localeSubFolder of localeFolders) {
|
||||||
|
const localeSubDir = join(localeDir, localeSubFolder);
|
||||||
|
const localeSubFiles = readdirSync(localeSubDir, {
|
||||||
|
withFileTypes: true,
|
||||||
|
})
|
||||||
|
.filter((dirent) => dirent.isFile())
|
||||||
|
.map((dirent) => dirent.name);
|
||||||
|
|
||||||
|
for (const localeSubFile of localeSubFiles) {
|
||||||
|
if (localeSubFile.endsWith(".ftl")) {
|
||||||
|
renameSync(
|
||||||
|
join(localeSubDir, localeSubFile),
|
||||||
|
join(localeSubDir, `${config.addonRef}-${localeSubFile}`)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
console.log("[Build] Addon prepare OK");
|
console.log("[Build] Addon prepare OK");
|
||||||
|
|
||||||
await zip.compressDir(
|
await zip.compressDir(
|
||||||
|
@ -6,7 +6,7 @@ import {
|
|||||||
UIExampleFactory,
|
UIExampleFactory,
|
||||||
} from "./modules/examples";
|
} from "./modules/examples";
|
||||||
import { config } from "../package.json";
|
import { config } from "../package.json";
|
||||||
import { getString, initLocale } from "./utils/locale";
|
import { getStringAsync, initLocale } from "./utils/locale";
|
||||||
import { registerPrefsScripts } from "./modules/preferenceScript";
|
import { registerPrefsScripts } from "./modules/preferenceScript";
|
||||||
|
|
||||||
async function onStartup() {
|
async function onStartup() {
|
||||||
@ -26,7 +26,7 @@ async function onStartup() {
|
|||||||
closeTime: -1,
|
closeTime: -1,
|
||||||
})
|
})
|
||||||
.createLine({
|
.createLine({
|
||||||
text: getString("startup.begin"),
|
text: await getStringAsync("startup-begin"),
|
||||||
type: "default",
|
type: "default",
|
||||||
progress: 0,
|
progress: 0,
|
||||||
})
|
})
|
||||||
@ -41,7 +41,7 @@ async function onStartup() {
|
|||||||
await Zotero.Promise.delay(1000);
|
await Zotero.Promise.delay(1000);
|
||||||
popupWin.changeLine({
|
popupWin.changeLine({
|
||||||
progress: 30,
|
progress: 30,
|
||||||
text: `[30%] ${getString("startup.begin")}`,
|
text: `[30%] ${await getStringAsync("startup-begin")}`,
|
||||||
});
|
});
|
||||||
|
|
||||||
UIExampleFactory.registerStyleSheet();
|
UIExampleFactory.registerStyleSheet();
|
||||||
@ -74,7 +74,7 @@ async function onStartup() {
|
|||||||
|
|
||||||
popupWin.changeLine({
|
popupWin.changeLine({
|
||||||
progress: 100,
|
progress: 100,
|
||||||
text: `[100%] ${getString("startup.finish")}`,
|
text: `[100%] ${await getStringAsync("startup-finish")}`,
|
||||||
});
|
});
|
||||||
popupWin.startCloseTimer(5000);
|
popupWin.startCloseTimer(5000);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { config } from "../../package.json";
|
import { config } from "../../package.json";
|
||||||
import { getString } from "../utils/locale";
|
import { getStringAsync } from "../utils/locale";
|
||||||
|
|
||||||
function example(
|
function example(
|
||||||
target: any,
|
target: any,
|
||||||
@ -71,13 +71,12 @@ export class BasicExampleFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@example
|
@example
|
||||||
static registerPrefs() {
|
static async registerPrefs() {
|
||||||
const prefOptions = {
|
const prefOptions = {
|
||||||
pluginID: config.addonID,
|
pluginID: config.addonID,
|
||||||
src: rootURI + "chrome/content/preferences.xhtml",
|
src: rootURI + "chrome/content/preferences.xhtml",
|
||||||
label: getString("prefs.title"),
|
label: await getStringAsync("prefs-title"),
|
||||||
image: `chrome://${config.addonRef}/content/icons/favicon.png`,
|
image: `chrome://${config.addonRef}/content/icons/favicon.png`,
|
||||||
extraDTD: [`chrome://${config.addonRef}/locale/overlay.dtd`],
|
|
||||||
defaultXUL: true,
|
defaultXUL: true,
|
||||||
};
|
};
|
||||||
ztoolkit.PreferencePane.register(prefOptions);
|
ztoolkit.PreferencePane.register(prefOptions);
|
||||||
@ -198,29 +197,29 @@ export class UIExampleFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@example
|
@example
|
||||||
static registerRightClickMenuItem() {
|
static async registerRightClickMenuItem() {
|
||||||
const menuIcon = `chrome://${config.addonRef}/content/icons/favicon@0.5x.png`;
|
const menuIcon = `chrome://${config.addonRef}/content/icons/favicon@0.5x.png`;
|
||||||
// item menuitem with icon
|
// item menuitem with icon
|
||||||
ztoolkit.Menu.register("item", {
|
ztoolkit.Menu.register("item", {
|
||||||
tag: "menuitem",
|
tag: "menuitem",
|
||||||
id: "zotero-itemmenu-addontemplate-test",
|
id: "zotero-itemmenu-addontemplate-test",
|
||||||
label: getString("menuitem.label"),
|
label: await getStringAsync("menuitem-label"),
|
||||||
commandListener: (ev) => addon.hooks.onDialogEvents("dialogExample"),
|
commandListener: (ev) => addon.hooks.onDialogEvents("dialogExample"),
|
||||||
icon: menuIcon,
|
icon: menuIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@example
|
@example
|
||||||
static registerRightClickMenuPopup() {
|
static async registerRightClickMenuPopup() {
|
||||||
ztoolkit.Menu.register(
|
ztoolkit.Menu.register(
|
||||||
"item",
|
"item",
|
||||||
{
|
{
|
||||||
tag: "menu",
|
tag: "menu",
|
||||||
label: getString("menupopup.label"),
|
label: await getStringAsync("menupopup-label"),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
tag: "menuitem",
|
tag: "menuitem",
|
||||||
label: getString("menuitem.submenulabel"),
|
label: await getStringAsync("menuitem-submenulabel"),
|
||||||
oncommand: "alert('Hello World! Sub Menuitem.')",
|
oncommand: "alert('Hello World! Sub Menuitem.')",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -233,14 +232,14 @@ export class UIExampleFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@example
|
@example
|
||||||
static registerWindowMenuWithSeparator() {
|
static async registerWindowMenuWithSeparator() {
|
||||||
ztoolkit.Menu.register("menuFile", {
|
ztoolkit.Menu.register("menuFile", {
|
||||||
tag: "menuseparator",
|
tag: "menuseparator",
|
||||||
});
|
});
|
||||||
// menu->File menuitem
|
// menu->File menuitem
|
||||||
ztoolkit.Menu.register("menuFile", {
|
ztoolkit.Menu.register("menuFile", {
|
||||||
tag: "menuitem",
|
tag: "menuitem",
|
||||||
label: getString("menuitem.filemenulabel"),
|
label: await getStringAsync("menuitem-filemenulabel"),
|
||||||
oncommand: "alert('Hello World! File Menuitem.')",
|
oncommand: "alert('Hello World! File Menuitem.')",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -346,9 +345,9 @@ export class UIExampleFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@example
|
@example
|
||||||
static registerLibraryTabPanel() {
|
static async registerLibraryTabPanel() {
|
||||||
const tabId = ztoolkit.LibraryTabPanel.register(
|
const tabId = ztoolkit.LibraryTabPanel.register(
|
||||||
getString("tabpanel.lib.tab.label"),
|
await getStringAsync("tabpanel-lib-tab-label"),
|
||||||
(panel: XUL.Element, win: Window) => {
|
(panel: XUL.Element, win: Window) => {
|
||||||
const elem = ztoolkit.UI.createElement(win.document, "vbox", {
|
const elem = ztoolkit.UI.createElement(win.document, "vbox", {
|
||||||
children: [
|
children: [
|
||||||
@ -392,7 +391,7 @@ export class UIExampleFactory {
|
|||||||
@example
|
@example
|
||||||
static async registerReaderTabPanel() {
|
static async registerReaderTabPanel() {
|
||||||
const tabId = await ztoolkit.ReaderTabPanel.register(
|
const tabId = await ztoolkit.ReaderTabPanel.register(
|
||||||
getString("tabpanel.reader.tab.label"),
|
await getStringAsync("tabpanel-reader-tab-label"),
|
||||||
(
|
(
|
||||||
panel: XUL.TabPanel | undefined,
|
panel: XUL.TabPanel | undefined,
|
||||||
deck: XUL.Deck,
|
deck: XUL.Deck,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { config } from "../../package.json";
|
import { config } from "../../package.json";
|
||||||
import { getString } from "../utils/locale";
|
import { getStringAsync } from "../utils/locale";
|
||||||
|
|
||||||
export function registerPrefsScripts(_window: Window) {
|
export async function registerPrefsScripts(_window: Window) {
|
||||||
// This function is called when the prefs window is opened
|
// This function is called when the prefs window is opened
|
||||||
// See addon/chrome/content/preferences.xul onpaneload
|
// See addon/chrome/content/preferences.xul onpaneload
|
||||||
if (!addon.data.prefs) {
|
if (!addon.data.prefs) {
|
||||||
@ -10,13 +10,13 @@ export function registerPrefsScripts(_window: Window) {
|
|||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
dataKey: "title",
|
dataKey: "title",
|
||||||
label: "prefs.table.title",
|
label: await getStringAsync("prefs-table-title"),
|
||||||
fixedWidth: true,
|
fixedWidth: true,
|
||||||
width: 100,
|
width: 100,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dataKey: "detail",
|
dataKey: "detail",
|
||||||
label: "prefs.table.detail",
|
label: await getStringAsync("prefs-table-detail"),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
rows: [
|
rows: [
|
||||||
@ -53,11 +53,7 @@ async function updatePrefsUI() {
|
|||||||
id: `${config.addonRef}-prefs-table`,
|
id: `${config.addonRef}-prefs-table`,
|
||||||
// Do not use setLocale, as it modifies the Zotero.Intl.strings
|
// Do not use setLocale, as it modifies the Zotero.Intl.strings
|
||||||
// Set locales directly to columns
|
// Set locales directly to columns
|
||||||
columns: addon.data.prefs?.columns.map((column) =>
|
columns: addon.data.prefs?.columns,
|
||||||
Object.assign(column, {
|
|
||||||
label: getString(column.label) || column.label,
|
|
||||||
})
|
|
||||||
),
|
|
||||||
showHeader: true,
|
showHeader: true,
|
||||||
multiSelect: true,
|
multiSelect: true,
|
||||||
staticColumns: true,
|
staticColumns: true,
|
||||||
|
@ -1,29 +1,52 @@
|
|||||||
import { config } from "../../package.json";
|
import { config } from "../../package.json";
|
||||||
|
import { waitUntil } from "./wait";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize locale data
|
* Initialize locale data
|
||||||
*/
|
*/
|
||||||
export function initLocale() {
|
export function initLocale() {
|
||||||
addon.data.locale = {
|
ztoolkit.UI.appendElement(
|
||||||
stringBundle: Components.classes["@mozilla.org/intl/stringbundle;1"]
|
{
|
||||||
.getService(Components.interfaces.nsIStringBundleService)
|
tag: "link",
|
||||||
.createBundle(`chrome://${config.addonRef}/locale/addon.properties`),
|
namespace: "html",
|
||||||
};
|
properties: {
|
||||||
|
rel: "localization",
|
||||||
|
href: `${config.addonRef}-addon.ftl`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
document.querySelector("linkset")!
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get locale string
|
* Get locale string
|
||||||
* @param localString
|
* @param localString
|
||||||
* @param noReload
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
export function getString(localString: string, noReload = false): string {
|
export function getString(localString: string): string {
|
||||||
try {
|
let result = "";
|
||||||
return addon.data.locale?.stringBundle.GetStringFromName(localString);
|
let flag = false;
|
||||||
} catch (e) {
|
getStringAsync(localString)
|
||||||
if (!noReload) {
|
.then((value) => {
|
||||||
initLocale();
|
result = value;
|
||||||
return getString(localString, true);
|
flag = true;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
ztoolkit.log(e);
|
||||||
|
flag = true;
|
||||||
|
});
|
||||||
|
const t = new Date().getTime();
|
||||||
|
while (!flag && t < new Date().getTime() - 3000) {
|
||||||
|
// wait until the string is loaded
|
||||||
}
|
}
|
||||||
return localString;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get locale string async
|
||||||
|
* @param localString
|
||||||
|
*/
|
||||||
|
export async function getStringAsync(localString: string): Promise<string> {
|
||||||
|
// @ts-ignore
|
||||||
|
return (await document.l10n.formatValue(localString)) || localString;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import { getString } from "./locale";
|
export { isWindowAlive };
|
||||||
|
|
||||||
export { isWindowAlive, localeWindow };
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the window is alive.
|
* Check if the window is alive.
|
||||||
@ -10,57 +8,3 @@ export { isWindowAlive, localeWindow };
|
|||||||
function isWindowAlive(win?: Window) {
|
function isWindowAlive(win?: Window) {
|
||||||
return win && !Components.utils.isDeadWrapper(win) && !win.closed;
|
return win && !Components.utils.isDeadWrapper(win) && !win.closed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Locale the elements in window with the locale-target attribute.
|
|
||||||
* Useful when the window is created dynamically.
|
|
||||||
* @example
|
|
||||||
* In HTML:
|
|
||||||
* ```html
|
|
||||||
* <div locale-target="innerHTML,title" title="elem.title">elem.text</div>
|
|
||||||
* ```
|
|
||||||
* In `addon/chrome/locale/en-US/addon.properties`:
|
|
||||||
* ```properties
|
|
||||||
* elem.text=Hello World
|
|
||||||
* elem.title=Locale example
|
|
||||||
* ```
|
|
||||||
* In `addon/chrome/locale/zh-CN/addon.properties`:
|
|
||||||
* ```properties
|
|
||||||
* elem.text=你好世界
|
|
||||||
* elem.title=多语言样例
|
|
||||||
* ```
|
|
||||||
* After locale:
|
|
||||||
*
|
|
||||||
* if locale is "en-US"
|
|
||||||
* ```html
|
|
||||||
* <div locale-target="innerHTML,title" title="Locale example">Hello World</div>
|
|
||||||
* ```
|
|
||||||
* else if locale is "zh-CN"
|
|
||||||
* ```html
|
|
||||||
* <div locale-target="innerHTML,title" title="多语言样例">你好世界</div>
|
|
||||||
* ```
|
|
||||||
* @param win
|
|
||||||
*/
|
|
||||||
function localeWindow(win: Window) {
|
|
||||||
Array.from(win.document.querySelectorAll("*[locale-target]")).forEach(
|
|
||||||
(elem) => {
|
|
||||||
const errorInfo = "Locale Error";
|
|
||||||
const locales = elem.getAttribute("locale-target")?.split(",");
|
|
||||||
locales?.forEach((key) => {
|
|
||||||
const isProp = key in elem;
|
|
||||||
try {
|
|
||||||
const localeString = getString(
|
|
||||||
(isProp ? (elem as any)[key] : elem.getAttribute(key)).trim() || ""
|
|
||||||
);
|
|
||||||
isProp
|
|
||||||
? ((elem as any)[key] = localeString)
|
|
||||||
: elem.setAttribute(key, localeString);
|
|
||||||
} catch (error) {
|
|
||||||
isProp
|
|
||||||
? ((elem as any)[key] = errorInfo)
|
|
||||||
: elem.setAttribute(key, errorInfo);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user