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)
 | 
			
		||||
 | 
			
		||||
> 👍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.
 | 
			
		||||
 | 
			
		||||
@ -40,6 +40,8 @@ If you are using this repo, I recommended that you put this badge ([![Using Zote
 | 
			
		||||
 | 
			
		||||
## 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;
 | 
			
		||||
- 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)
 | 
			
		||||
@ -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.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<details style="text-indent: 2em">
 | 
			
		||||
<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>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Debug in Zotero
 | 
			
		||||
 | 
			
		||||
You can also:
 | 
			
		||||
 | 
			
		||||
@ -1,18 +1,22 @@
 | 
			
		||||
<linkset>
 | 
			
		||||
  <html:link rel="localization" href="__addonRef__-preferences.ftl" />
 | 
			
		||||
</linkset>
 | 
			
		||||
<vbox
 | 
			
		||||
  id="zotero-prefpane-__addonRef__"
 | 
			
		||||
  onload="Zotero.__addonInstance__.hooks.onPrefsEvent('load', {window})"
 | 
			
		||||
>
 | 
			
		||||
  <groupbox>
 | 
			
		||||
    <label><html:h2>&zotero.__addonRef__.pref.title;</html:h2></label>
 | 
			
		||||
    <label><html:h2 data-l10n-id="pref-title"></html:h2></label>
 | 
			
		||||
    <checkbox
 | 
			
		||||
      id="zotero-prefpane-__addonRef__-enable"
 | 
			
		||||
      label="&zotero.__addonRef__.pref.enable.label;"
 | 
			
		||||
      preference="extensions.zotero.__addonRef__.enable"
 | 
			
		||||
      data-l10n-id="pref-enable"
 | 
			
		||||
    />
 | 
			
		||||
    <hbox>
 | 
			
		||||
      <html:label for="zotero-prefpane-__addonRef__-input"
 | 
			
		||||
        >&zotero.__addonRef__.pref.input.label;</html:label
 | 
			
		||||
      >
 | 
			
		||||
      <html:label
 | 
			
		||||
        for="zotero-prefpane-__addonRef__-input"
 | 
			
		||||
        data-l10n-id="pref-input"
 | 
			
		||||
      ></html:label>
 | 
			
		||||
      <html:input
 | 
			
		||||
        type="text"
 | 
			
		||||
        id="zotero-prefpane-__addonRef__-input"
 | 
			
		||||
@ -25,7 +29,8 @@
 | 
			
		||||
  </groupbox>
 | 
			
		||||
</vbox>
 | 
			
		||||
<vbox>
 | 
			
		||||
  <label
 | 
			
		||||
    value="&zotero.__addonRef__.help.version.label;  &zotero.__addonRef__.help.releasetime.label;"
 | 
			
		||||
  ></label>
 | 
			
		||||
  <html:label
 | 
			
		||||
    data-l10n-id="pref-help"
 | 
			
		||||
    data-l10n-args='{"time": "__buildTime__","name": "__addonName__","version":"__buildVersion__"}'
 | 
			
		||||
  ></html:label>
 | 
			
		||||
</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,
 | 
			
		||||
  readdirSync,
 | 
			
		||||
  rmSync,
 | 
			
		||||
  renameSync,
 | 
			
		||||
} from "fs";
 | 
			
		||||
import { env, exit } from "process";
 | 
			
		||||
import replaceInFile from "replace-in-file";
 | 
			
		||||
@ -158,6 +159,30 @@ async function main() {
 | 
			
		||||
 | 
			
		||||
  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");
 | 
			
		||||
 | 
			
		||||
  await zip.compressDir(
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,7 @@ import {
 | 
			
		||||
  UIExampleFactory,
 | 
			
		||||
} from "./modules/examples";
 | 
			
		||||
import { config } from "../package.json";
 | 
			
		||||
import { getString, initLocale } from "./utils/locale";
 | 
			
		||||
import { getStringAsync, initLocale } from "./utils/locale";
 | 
			
		||||
import { registerPrefsScripts } from "./modules/preferenceScript";
 | 
			
		||||
 | 
			
		||||
async function onStartup() {
 | 
			
		||||
@ -26,7 +26,7 @@ async function onStartup() {
 | 
			
		||||
    closeTime: -1,
 | 
			
		||||
  })
 | 
			
		||||
    .createLine({
 | 
			
		||||
      text: getString("startup.begin"),
 | 
			
		||||
      text: await getStringAsync("startup-begin"),
 | 
			
		||||
      type: "default",
 | 
			
		||||
      progress: 0,
 | 
			
		||||
    })
 | 
			
		||||
@ -41,7 +41,7 @@ async function onStartup() {
 | 
			
		||||
  await Zotero.Promise.delay(1000);
 | 
			
		||||
  popupWin.changeLine({
 | 
			
		||||
    progress: 30,
 | 
			
		||||
    text: `[30%] ${getString("startup.begin")}`,
 | 
			
		||||
    text: `[30%] ${await getStringAsync("startup-begin")}`,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  UIExampleFactory.registerStyleSheet();
 | 
			
		||||
@ -74,7 +74,7 @@ async function onStartup() {
 | 
			
		||||
 | 
			
		||||
  popupWin.changeLine({
 | 
			
		||||
    progress: 100,
 | 
			
		||||
    text: `[100%] ${getString("startup.finish")}`,
 | 
			
		||||
    text: `[100%] ${await getStringAsync("startup-finish")}`,
 | 
			
		||||
  });
 | 
			
		||||
  popupWin.startCloseTimer(5000);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import { config } from "../../package.json";
 | 
			
		||||
import { getString } from "../utils/locale";
 | 
			
		||||
import { getStringAsync } from "../utils/locale";
 | 
			
		||||
 | 
			
		||||
function example(
 | 
			
		||||
  target: any,
 | 
			
		||||
@ -71,13 +71,12 @@ export class BasicExampleFactory {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @example
 | 
			
		||||
  static registerPrefs() {
 | 
			
		||||
  static async registerPrefs() {
 | 
			
		||||
    const prefOptions = {
 | 
			
		||||
      pluginID: config.addonID,
 | 
			
		||||
      src: rootURI + "chrome/content/preferences.xhtml",
 | 
			
		||||
      label: getString("prefs.title"),
 | 
			
		||||
      label: await getStringAsync("prefs-title"),
 | 
			
		||||
      image: `chrome://${config.addonRef}/content/icons/favicon.png`,
 | 
			
		||||
      extraDTD: [`chrome://${config.addonRef}/locale/overlay.dtd`],
 | 
			
		||||
      defaultXUL: true,
 | 
			
		||||
    };
 | 
			
		||||
    ztoolkit.PreferencePane.register(prefOptions);
 | 
			
		||||
@ -198,29 +197,29 @@ export class UIExampleFactory {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @example
 | 
			
		||||
  static registerRightClickMenuItem() {
 | 
			
		||||
  static async registerRightClickMenuItem() {
 | 
			
		||||
    const menuIcon = `chrome://${config.addonRef}/content/icons/favicon@0.5x.png`;
 | 
			
		||||
    // item menuitem with icon
 | 
			
		||||
    ztoolkit.Menu.register("item", {
 | 
			
		||||
      tag: "menuitem",
 | 
			
		||||
      id: "zotero-itemmenu-addontemplate-test",
 | 
			
		||||
      label: getString("menuitem.label"),
 | 
			
		||||
      label: await getStringAsync("menuitem-label"),
 | 
			
		||||
      commandListener: (ev) => addon.hooks.onDialogEvents("dialogExample"),
 | 
			
		||||
      icon: menuIcon,
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @example
 | 
			
		||||
  static registerRightClickMenuPopup() {
 | 
			
		||||
  static async registerRightClickMenuPopup() {
 | 
			
		||||
    ztoolkit.Menu.register(
 | 
			
		||||
      "item",
 | 
			
		||||
      {
 | 
			
		||||
        tag: "menu",
 | 
			
		||||
        label: getString("menupopup.label"),
 | 
			
		||||
        label: await getStringAsync("menupopup-label"),
 | 
			
		||||
        children: [
 | 
			
		||||
          {
 | 
			
		||||
            tag: "menuitem",
 | 
			
		||||
            label: getString("menuitem.submenulabel"),
 | 
			
		||||
            label: await getStringAsync("menuitem-submenulabel"),
 | 
			
		||||
            oncommand: "alert('Hello World! Sub Menuitem.')",
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
@ -233,14 +232,14 @@ export class UIExampleFactory {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @example
 | 
			
		||||
  static registerWindowMenuWithSeparator() {
 | 
			
		||||
  static async registerWindowMenuWithSeparator() {
 | 
			
		||||
    ztoolkit.Menu.register("menuFile", {
 | 
			
		||||
      tag: "menuseparator",
 | 
			
		||||
    });
 | 
			
		||||
    // menu->File menuitem
 | 
			
		||||
    ztoolkit.Menu.register("menuFile", {
 | 
			
		||||
      tag: "menuitem",
 | 
			
		||||
      label: getString("menuitem.filemenulabel"),
 | 
			
		||||
      label: await getStringAsync("menuitem-filemenulabel"),
 | 
			
		||||
      oncommand: "alert('Hello World! File Menuitem.')",
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
@ -346,9 +345,9 @@ export class UIExampleFactory {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @example
 | 
			
		||||
  static registerLibraryTabPanel() {
 | 
			
		||||
  static async registerLibraryTabPanel() {
 | 
			
		||||
    const tabId = ztoolkit.LibraryTabPanel.register(
 | 
			
		||||
      getString("tabpanel.lib.tab.label"),
 | 
			
		||||
      await getStringAsync("tabpanel-lib-tab-label"),
 | 
			
		||||
      (panel: XUL.Element, win: Window) => {
 | 
			
		||||
        const elem = ztoolkit.UI.createElement(win.document, "vbox", {
 | 
			
		||||
          children: [
 | 
			
		||||
@ -392,7 +391,7 @@ export class UIExampleFactory {
 | 
			
		||||
  @example
 | 
			
		||||
  static async registerReaderTabPanel() {
 | 
			
		||||
    const tabId = await ztoolkit.ReaderTabPanel.register(
 | 
			
		||||
      getString("tabpanel.reader.tab.label"),
 | 
			
		||||
      await getStringAsync("tabpanel-reader-tab-label"),
 | 
			
		||||
      (
 | 
			
		||||
        panel: XUL.TabPanel | undefined,
 | 
			
		||||
        deck: XUL.Deck,
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
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
 | 
			
		||||
  // See addon/chrome/content/preferences.xul onpaneload
 | 
			
		||||
  if (!addon.data.prefs) {
 | 
			
		||||
@ -10,13 +10,13 @@ export function registerPrefsScripts(_window: Window) {
 | 
			
		||||
      columns: [
 | 
			
		||||
        {
 | 
			
		||||
          dataKey: "title",
 | 
			
		||||
          label: "prefs.table.title",
 | 
			
		||||
          label: await getStringAsync("prefs-table-title"),
 | 
			
		||||
          fixedWidth: true,
 | 
			
		||||
          width: 100,
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          dataKey: "detail",
 | 
			
		||||
          label: "prefs.table.detail",
 | 
			
		||||
          label: await getStringAsync("prefs-table-detail"),
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
      rows: [
 | 
			
		||||
@ -53,11 +53,7 @@ async function updatePrefsUI() {
 | 
			
		||||
      id: `${config.addonRef}-prefs-table`,
 | 
			
		||||
      // Do not use setLocale, as it modifies the Zotero.Intl.strings
 | 
			
		||||
      // Set locales directly to columns
 | 
			
		||||
      columns: addon.data.prefs?.columns.map((column) =>
 | 
			
		||||
        Object.assign(column, {
 | 
			
		||||
          label: getString(column.label) || column.label,
 | 
			
		||||
        })
 | 
			
		||||
      ),
 | 
			
		||||
      columns: addon.data.prefs?.columns,
 | 
			
		||||
      showHeader: true,
 | 
			
		||||
      multiSelect: true,
 | 
			
		||||
      staticColumns: true,
 | 
			
		||||
 | 
			
		||||
@ -1,29 +1,52 @@
 | 
			
		||||
import { config } from "../../package.json";
 | 
			
		||||
import { waitUntil } from "./wait";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initialize locale data
 | 
			
		||||
 */
 | 
			
		||||
export function initLocale() {
 | 
			
		||||
  addon.data.locale = {
 | 
			
		||||
    stringBundle: Components.classes["@mozilla.org/intl/stringbundle;1"]
 | 
			
		||||
      .getService(Components.interfaces.nsIStringBundleService)
 | 
			
		||||
      .createBundle(`chrome://${config.addonRef}/locale/addon.properties`),
 | 
			
		||||
  };
 | 
			
		||||
  ztoolkit.UI.appendElement(
 | 
			
		||||
    {
 | 
			
		||||
      tag: "link",
 | 
			
		||||
      namespace: "html",
 | 
			
		||||
      properties: {
 | 
			
		||||
        rel: "localization",
 | 
			
		||||
        href: `${config.addonRef}-addon.ftl`,
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    document.querySelector("linkset")!
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get locale string
 | 
			
		||||
 * @param localString
 | 
			
		||||
 * @param noReload
 | 
			
		||||
 * @deprecated
 | 
			
		||||
 */
 | 
			
		||||
export function getString(localString: string, noReload = false): string {
 | 
			
		||||
  try {
 | 
			
		||||
    return addon.data.locale?.stringBundle.GetStringFromName(localString);
 | 
			
		||||
  } catch (e) {
 | 
			
		||||
    if (!noReload) {
 | 
			
		||||
      initLocale();
 | 
			
		||||
      return getString(localString, true);
 | 
			
		||||
export function getString(localString: string): string {
 | 
			
		||||
  let result = "";
 | 
			
		||||
  let flag = false;
 | 
			
		||||
  getStringAsync(localString)
 | 
			
		||||
    .then((value) => {
 | 
			
		||||
      result = value;
 | 
			
		||||
      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, localeWindow };
 | 
			
		||||
export { isWindowAlive };
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if the window is alive.
 | 
			
		||||
@ -10,57 +8,3 @@ export { isWindowAlive, localeWindow };
 | 
			
		||||
function isWindowAlive(win?: Window) {
 | 
			
		||||
  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