Merge branch 'windingwind:bootstrap' into bootstrap
This commit is contained in:
		
						commit
						0f33389dae
					
				
							
								
								
									
										183
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										183
									
								
								README.md
									
									
									
									
									
								
							@ -60,7 +60,7 @@ Search `@example` in `src/examples.ts`. The examples are called in `src/hooks.ts
 | 
			
		||||
 | 
			
		||||
### UI Examples
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
- registerStyleSheet(the official make-it-red example)
 | 
			
		||||
- registerRightClickMenuItem
 | 
			
		||||
@ -71,11 +71,33 @@ Search `@example` in `src/examples.ts`. The examples are called in `src/hooks.ts
 | 
			
		||||
- registerCustomCellRenderer
 | 
			
		||||
- registerLibraryTabPanel
 | 
			
		||||
- registerReaderTabPanel
 | 
			
		||||
- unregisterUIExamples
 | 
			
		||||
 | 
			
		||||
### Preference Pane Examples
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
- Preferences bindings
 | 
			
		||||
- UI Events
 | 
			
		||||
- Tabel
 | 
			
		||||
- Locale
 | 
			
		||||
 | 
			
		||||
See [`src/modules/preferenceScript.ts`](./src/modules/preferenceScript.ts)
 | 
			
		||||
 | 
			
		||||
## Quick Start Guide
 | 
			
		||||
 | 
			
		||||
- Fork this repo;
 | 
			
		||||
### Install Pre-built `xpi`
 | 
			
		||||
 | 
			
		||||
See how the examples work by directly downloading the `xpi` file from GitHub release and install it to your Zotero.
 | 
			
		||||
 | 
			
		||||
This is also how your plugin will be released and used by others.
 | 
			
		||||
 | 
			
		||||
> The release do not promise any real functions. It is probably not up-to-date.
 | 
			
		||||
>
 | 
			
		||||
> The `xpi` package is a zip file. However, please don't modify it directly. Modify the source code and build it.
 | 
			
		||||
 | 
			
		||||
### Build from Source
 | 
			
		||||
 | 
			
		||||
- Fork this repo/Click `Use this template`;
 | 
			
		||||
- Git clone the forked repo;
 | 
			
		||||
- Enter the repo folder;
 | 
			
		||||
- Modify the settings in `./package.json`, including:
 | 
			
		||||
@ -104,6 +126,66 @@ Search `@example` in `src/examples.ts`. The examples are called in `src/hooks.ts
 | 
			
		||||
> - This environment variable is stored in `Zotero.AddonTemplate.data.env`. The outputs to console is disabled in prod mode.
 | 
			
		||||
> - You can decide what users cannot see/use based on this variable.
 | 
			
		||||
 | 
			
		||||
### Release
 | 
			
		||||
 | 
			
		||||
To build and release, use
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
# A release-it command: version increase, npm run build, git push, and GitHub release
 | 
			
		||||
# You need to set the environment variable GITHUB_TOKEN https://github.com/settings/tokens
 | 
			
		||||
# release-it: https://github.com/release-it/release-it
 | 
			
		||||
npm run release
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Setup Development Environment
 | 
			
		||||
 | 
			
		||||
1. Install a beta version of Zotero: https://www.zotero.org/support/beta_builds (Zotero 7 beta: https://www.zotero.org/support/dev/zotero_7_for_developers)
 | 
			
		||||
 | 
			
		||||
2. Install Firefox 60(for Zotero 6)/Firefox 102(for Zotero 7)
 | 
			
		||||
 | 
			
		||||
3. Copy zotero command line config file. Modify the commands that starts your installation of the beta Zotero.
 | 
			
		||||
 | 
			
		||||
> (Optional) Do this only once: Start the beta Zotero with `/path/to/zotero -p`. Create a new profile and use it as your development profile.
 | 
			
		||||
> Use `/path/to/zotero -p {profile_name}` to specify which profile to run with.
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
cp ./scripts/zotero-cmd-default.json ./scripts/zotero-cmd.json
 | 
			
		||||
vim ./scripts/zotero-cmd.json
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
4. Setup plugin development environment following this [link](https://www.zotero.org/support/dev/client_coding/plugin_development#setting_up_a_plugin_development_environment).
 | 
			
		||||
 | 
			
		||||
5. Build plugin and restart Zotero with `npm run restart`.
 | 
			
		||||
 | 
			
		||||
6. Launch Firefox 60(Zotero 6)/Firefox 102(Zotero 7)
 | 
			
		||||
 | 
			
		||||
7. In Firefox, go to devtools, go to settings, click "enable remote debugging" and the one next to it that's also about debugging
 | 
			
		||||
 | 
			
		||||
> Press `shift+F8` in FF 60, or enter `about:debugging#/setup` in FF 102.
 | 
			
		||||
 | 
			
		||||
8. In Zotero, go to setting, advanced, config editor, look up "debugging" and click on "allow remote debugging".
 | 
			
		||||
 | 
			
		||||
9. Connect to Zotero in Firefox.
 | 
			
		||||
 | 
			
		||||
> In FF 60, click the hamburger menu in the top right -> web developer -> Connect..., then enter `localhost:6100`.
 | 
			
		||||
 | 
			
		||||
> In FF 102, enter `localhost:6100` in the bottom input of remote-debugging page and click `add`.
 | 
			
		||||
 | 
			
		||||
10. Click `connect` in the leftside-bar of Firefox remote-debugging page.
 | 
			
		||||
 | 
			
		||||
11. Click "Inspect Main Process"
 | 
			
		||||
 | 
			
		||||
### Debug in Zotero
 | 
			
		||||
 | 
			
		||||
You can also:
 | 
			
		||||
 | 
			
		||||
- Test code snipastes in Tools->Developer->Run Javascript;
 | 
			
		||||
- Debug output with `Zotero.debug()`. Find the outputs in Help->Debug Output Logging->View Output;
 | 
			
		||||
- Debug UI. Zotero is built on the Firefox XUL framework. Debug XUL UI with software like [XUL Explorer](https://udn.realityripple.com/docs/Archive/Mozilla/XUL_Explorer).
 | 
			
		||||
  > XUL Documentation: http://www.devdoc.net/web/developer.mozilla.org/en-US/docs/XUL.html
 | 
			
		||||
 | 
			
		||||
## Details
 | 
			
		||||
 | 
			
		||||
### About Hooks
 | 
			
		||||
 | 
			
		||||
> See also [`src/hooks.ts`](https://github.com/windingwind/zotero-plugin-template/blob/bootstrap/src/hooks.ts)
 | 
			
		||||
@ -165,10 +247,38 @@ Remember to call `unregister()` on plugin unload.
 | 
			
		||||
 | 
			
		||||
The plugin template provides new APIs for bootstrap plugins. We have two reasons to use these APIs, instead of the `createElement/createElementNS`:
 | 
			
		||||
 | 
			
		||||
- In bootstrap mode, plugins have to clean up all UI elements on exit (disable or uninstall), which is very annoying. Using the `createElement`, the plugin template will maintain these elements. Just `unregister` on exit.
 | 
			
		||||
- Zotero 7 requires createElement()/createElementNS() → createXULElement() for remaining XUL elements, while Zotero 6 doesn't support `createXULElement`. Using `createElement`, it switches API depending on the current platform automatically.
 | 
			
		||||
- In bootstrap mode, plugins have to clean up all UI elements on exit (disable or uninstall), which is very annoying. Using the `createElement`, the plugin template will maintain these elements. Just `unregisterAll` at the exit.
 | 
			
		||||
- Zotero 7 requires createElement()/createElementNS() → createXULElement() for remaining XUL elements, while Zotero 6 doesn't support `createXULElement`. The React.createElement-like API `createElement` detects namespace(xul/html/svg) and creates elements automatically, with the return element in the corresponding TS element type.
 | 
			
		||||
 | 
			
		||||
There are more advanced APIs for creating elements in batch: `creatElementsFromJSON`. Input an element tree in JSON and return a fragment/element. These elements are also maintained by this plugin template.
 | 
			
		||||
```ts
 | 
			
		||||
createElement(document, "div"); // returns HTMLDivElement
 | 
			
		||||
createElement(document, "hbox"); // returns XUL.Box
 | 
			
		||||
createElement(document, "button", { namespace: "xul" }); // manually set namespace. returns XUL.Button
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### About Build
 | 
			
		||||
 | 
			
		||||
Use Esbuild to build `.ts` source code to `.js`.
 | 
			
		||||
 | 
			
		||||
Use `replace-in-file` to replace keywords and configurations defined in `package.json` in non-build files (`.xul/xhtml`, `.dtd`, and `.properties`).
 | 
			
		||||
 | 
			
		||||
Steps in `scripts/build.js`:
 | 
			
		||||
 | 
			
		||||
1. Clean `./builds`
 | 
			
		||||
2. Copy `./addon` to `./builds`
 | 
			
		||||
3. Esbuild to `./builds/addon/chrome/content/scripts`
 | 
			
		||||
4. Replace `__buildVersion__` and `__buildTime__` in `./builds/addon`
 | 
			
		||||
5. Zip the `./builds/addon` to `./builds/*.xpi`
 | 
			
		||||
 | 
			
		||||
### About Zotero API
 | 
			
		||||
 | 
			
		||||
Zotero docs are outdated and incomplete. Clone https://github.com/zotero/zotero and search the keyword globally.
 | 
			
		||||
 | 
			
		||||
> ⭐The [zotero-types](https://github.com/windingwind/zotero-types) provides most frequently used Zotero APIs. It's included in this template by default. Your IDE would provide hint for most of the APIs.
 | 
			
		||||
 | 
			
		||||
A trick for finding the API you want:
 | 
			
		||||
 | 
			
		||||
Search the UI label in `.xul`(`.xhtml`)/`.dtd`/`.properties` files, find the corresponding key in locale file. Then search this keys in `.js`/`.jsx` files.
 | 
			
		||||
 | 
			
		||||
### Directory Structure
 | 
			
		||||
 | 
			
		||||
@ -233,67 +343,6 @@ This section shows the directory structure of a template.
 | 
			
		||||
       └─ progressWindow.ts     # progressWindow tool
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Build
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
# A release-it command: version increase, npm run build, git push, and GitHub release
 | 
			
		||||
# You need to set the environment variable GITHUB_TOKEN https://github.com/settings/tokens
 | 
			
		||||
# release-it: https://github.com/release-it/release-it
 | 
			
		||||
npm run release
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Alternatively, build it directly using build.js: `npm run build`
 | 
			
		||||
 | 
			
		||||
### Build Steps
 | 
			
		||||
 | 
			
		||||
1. Clean `./builds`
 | 
			
		||||
2. Copy `./addon` to `./builds`
 | 
			
		||||
3. Esbuild to `./builds/addon/chrome/content/scripts`
 | 
			
		||||
4. Replace `__buildVersion__` and `__buildTime__` in `./builds/addon`
 | 
			
		||||
5. Zip the `./builds/addon` to `./builds/*.xpi`
 | 
			
		||||
 | 
			
		||||
### Debug
 | 
			
		||||
 | 
			
		||||
1. Copy zotero command line config file. Modify the commands.
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
cp ./scripts/zotero-cmd-default.json ./scripts/zotero-cmd.json
 | 
			
		||||
vim ./scripts/zotero-cmd.json
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
2. Setup plugin development environment following this [link](https://www.zotero.org/support/dev/client_coding/plugin_development#setting_up_a_plugin_development_environment).
 | 
			
		||||
 | 
			
		||||
3. Build plugin and restart Zotero with this npm command.
 | 
			
		||||
 | 
			
		||||
4. Launch Firefox 60
 | 
			
		||||
5. In Firefox, go to devtools, go to settings, click "enable remote debugging" and the one next to it that's also about debugging(or press `shift+F8`).
 | 
			
		||||
6. In Zotero, go to setting, advanced, config editor, look up "debugging" and click on "allow remote debugging"
 | 
			
		||||
7. In Firefox, click the hamburger menu in the top right -> web developer -> Connect...
 | 
			
		||||
8. Enter localhost:6100
 | 
			
		||||
9. Connect
 | 
			
		||||
10. Click "Inspect Main Process"
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
npm run restart
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
You can also debug code in these ways:
 | 
			
		||||
 | 
			
		||||
- Test code segments in Tools->Developer->Run Javascript;
 | 
			
		||||
- Debug output with `Zotero.debug()`. Find the outputs in Help->Debug Output Logging->View Output;
 | 
			
		||||
- UI debug. Zotero is built on the Firefox XUL framework. Debug XUL UI with software like [XUL Explorer](https://udn.realityripple.com/docs/Archive/Mozilla/XUL_Explorer).
 | 
			
		||||
  > XUL Documents:  
 | 
			
		||||
  > https://www.xul.fr/tutorial/  
 | 
			
		||||
  > http://www.xulplanet.com/
 | 
			
		||||
 | 
			
		||||
### Development
 | 
			
		||||
 | 
			
		||||
**Search for a Zotero API**  
 | 
			
		||||
Zotero docs are outdated or incomplete. Searching the source code of Zotero is unavoidable.  
 | 
			
		||||
Clone https://github.com/zotero/zotero and search the keyword globally. You can search the UI text in `.xul`/`.dtd` files, and then search the keys of the text value in `.js`/`.xul` files.
 | 
			
		||||
 | 
			
		||||
> ⭐The [zotero-types](https://github.com/windingwind/zotero-types) provides most frequently used Zotero APIs. It's included in this template by default.
 | 
			
		||||
 | 
			
		||||
## Disclaimer
 | 
			
		||||
 | 
			
		||||
Use this code under AGPL. No warranties are provided. Keep the laws of your locality in mind!
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,8 @@
 | 
			
		||||
    "build-dev": "cross-env NODE_ENV=development node scripts/build.js",
 | 
			
		||||
    "build-prod": "cross-env NODE_ENV=production node scripts/build.js",
 | 
			
		||||
    "build": "npm run build-prod",
 | 
			
		||||
    "start-z6": "node scripts/start.js --z 6",
 | 
			
		||||
    "start-z7": "node scripts/start.js --z 7",
 | 
			
		||||
    "start": "node scripts/start.js",
 | 
			
		||||
    "stop": "node scripts/stop.js",
 | 
			
		||||
    "restart-dev": "npm run build-dev && npm run stop && npm run start",
 | 
			
		||||
@ -33,7 +35,7 @@
 | 
			
		||||
  },
 | 
			
		||||
  "homepage": "https://github.com/windingwind/zotero-addon-template#readme",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "zotero-plugin-toolkit": "^1.0.3"
 | 
			
		||||
    "zotero-plugin-toolkit": "^1.0.4"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@types/node": "^18.11.17",
 | 
			
		||||
@ -42,6 +44,7 @@
 | 
			
		||||
    "esbuild": "^0.16.10",
 | 
			
		||||
    "release-it": "^15.6.0",
 | 
			
		||||
    "replace-in-file": "^6.3.5",
 | 
			
		||||
    "minimist": "^1.2.7",
 | 
			
		||||
    "zotero-types": "^1.0.0"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,25 @@
 | 
			
		||||
const { execSync } = require("child_process");
 | 
			
		||||
const { exit } = require("process");
 | 
			
		||||
const { startZotero } = require("./zotero-cmd.json");
 | 
			
		||||
const { exec } = require("./zotero-cmd.json");
 | 
			
		||||
 | 
			
		||||
// Run node start.js -h for help
 | 
			
		||||
const args = require("minimist")(process.argv.slice(2));
 | 
			
		||||
 | 
			
		||||
if (args.help || args.h) {
 | 
			
		||||
  console.log("Start Zotero Args:");
 | 
			
		||||
  console.log(
 | 
			
		||||
    "--zotero(-z): Zotero exec key in zotero-cmd.json. Default the first one."
 | 
			
		||||
  );
 | 
			
		||||
  console.log("--profile(-p): Zotero profile name.");
 | 
			
		||||
  exit(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const zoteroPath = exec[args.zotero || args.z || Object.keys(exec)[0]];
 | 
			
		||||
const profile = args.profile || args.p;
 | 
			
		||||
 | 
			
		||||
const startZotero = `${zoteroPath} --debugger --purgecaches ${
 | 
			
		||||
  profile ? `-p ${profile}` : ""
 | 
			
		||||
}`;
 | 
			
		||||
 | 
			
		||||
execSync(startZotero);
 | 
			
		||||
exit(0);
 | 
			
		||||
 | 
			
		||||
@ -2,5 +2,8 @@
 | 
			
		||||
  "usage": "Copy and rename this file to zotero-cmd.json. Edit the cmd.",
 | 
			
		||||
  "killZoteroWindows": "taskkill /f /im zotero.exe",
 | 
			
		||||
  "killZoteroUnix": "kill -9 $(ps -x | grep zotero)",
 | 
			
		||||
  "startZotero": "/path/to/zotero.exe --debugger --purgecaches"
 | 
			
		||||
  "exec": {
 | 
			
		||||
    "6": "/path/to/zotero6.exe",
 | 
			
		||||
    "7": "/path/to/zotero7.exe"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -15,7 +15,7 @@ if (!basicTool.getGlobal("Zotero").AddonTemplate) {
 | 
			
		||||
  _globalThis.ztoolkit = addon.data.ztoolkit;
 | 
			
		||||
  ztoolkit.basicOptions.log.prefix = `[${config.addonName}]`;
 | 
			
		||||
  ztoolkit.basicOptions.log.disableConsole = addon.data.env === "production";
 | 
			
		||||
  ztoolkit.UI.elementOptions.enableElementJSONLog =
 | 
			
		||||
  ztoolkit.UI.basicOptions.ui.enableElementJSONLog =
 | 
			
		||||
    addon.data.env === "development";
 | 
			
		||||
  Zotero.AddonTemplate = addon;
 | 
			
		||||
  // Trigger addon hook for initialization
 | 
			
		||||
 | 
			
		||||
@ -184,14 +184,13 @@ export class KeyExampleFactory {
 | 
			
		||||
export class UIExampleFactory {
 | 
			
		||||
  @example
 | 
			
		||||
  static registerStyleSheet() {
 | 
			
		||||
    const styles = ztoolkit.UI.creatElementsFromJSON(document, {
 | 
			
		||||
      tag: "link",
 | 
			
		||||
      directAttributes: {
 | 
			
		||||
    const styles = ztoolkit.UI.createElement(document, "link", {
 | 
			
		||||
      properties: {
 | 
			
		||||
        type: "text/css",
 | 
			
		||||
        rel: "stylesheet",
 | 
			
		||||
        href: `chrome://${config.addonRef}/content/zoteroPane.css`,
 | 
			
		||||
      },
 | 
			
		||||
    }) as HTMLLinkElement;
 | 
			
		||||
    });
 | 
			
		||||
    document.documentElement.appendChild(styles);
 | 
			
		||||
    document
 | 
			
		||||
      .getElementById("zotero-item-pane-content")
 | 
			
		||||
@ -218,7 +217,7 @@ export class UIExampleFactory {
 | 
			
		||||
      {
 | 
			
		||||
        tag: "menu",
 | 
			
		||||
        label: getString("menupopup.label"),
 | 
			
		||||
        subElementOptions: [
 | 
			
		||||
        children: [
 | 
			
		||||
          {
 | 
			
		||||
            tag: "menuitem",
 | 
			
		||||
            label: getString("menuitem.submenulabel"),
 | 
			
		||||
@ -313,28 +312,24 @@ export class UIExampleFactory {
 | 
			
		||||
    const tabId = ztoolkit.LibraryTabPanel.register(
 | 
			
		||||
      getString("tabpanel.lib.tab.label"),
 | 
			
		||||
      (panel: XUL.Element, win: Window) => {
 | 
			
		||||
        const elem = ztoolkit.UI.creatElementsFromJSON(win.document, {
 | 
			
		||||
          tag: "vbox",
 | 
			
		||||
          namespace: "xul",
 | 
			
		||||
          subElementOptions: [
 | 
			
		||||
        const elem = ztoolkit.UI.createElement(win.document, "vbox", {
 | 
			
		||||
          children: [
 | 
			
		||||
            {
 | 
			
		||||
              tag: "h2",
 | 
			
		||||
              namespace: "html",
 | 
			
		||||
              directAttributes: {
 | 
			
		||||
              properties: {
 | 
			
		||||
                innerText: "Hello World!",
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              tag: "div",
 | 
			
		||||
              namespace: "html",
 | 
			
		||||
              directAttributes: {
 | 
			
		||||
              properties: {
 | 
			
		||||
                innerText: "This is a library tab.",
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              tag: "button",
 | 
			
		||||
              namespace: "html",
 | 
			
		||||
              directAttributes: {
 | 
			
		||||
              properties: {
 | 
			
		||||
                innerText: "Unregister",
 | 
			
		||||
              },
 | 
			
		||||
              listeners: [
 | 
			
		||||
@ -373,46 +368,40 @@ export class UIExampleFactory {
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
        ztoolkit.log(reader);
 | 
			
		||||
        const elem = ztoolkit.UI.creatElementsFromJSON(win.document, {
 | 
			
		||||
          tag: "vbox",
 | 
			
		||||
        const elem = ztoolkit.UI.createElement(win.document, "vbox", {
 | 
			
		||||
          id: `${config.addonRef}-${reader._instanceID}-extra-reader-tab-div`,
 | 
			
		||||
          namespace: "xul",
 | 
			
		||||
          // This is important! Don't create content for multiple times
 | 
			
		||||
          // ignoreIfExists: true,
 | 
			
		||||
          removeIfExists: true,
 | 
			
		||||
          subElementOptions: [
 | 
			
		||||
          children: [
 | 
			
		||||
            {
 | 
			
		||||
              tag: "h2",
 | 
			
		||||
              namespace: "html",
 | 
			
		||||
              directAttributes: {
 | 
			
		||||
              properties: {
 | 
			
		||||
                innerText: "Hello World!",
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              tag: "div",
 | 
			
		||||
              namespace: "html",
 | 
			
		||||
              directAttributes: {
 | 
			
		||||
              properties: {
 | 
			
		||||
                innerText: "This is a reader tab.",
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              tag: "div",
 | 
			
		||||
              namespace: "html",
 | 
			
		||||
              directAttributes: {
 | 
			
		||||
              properties: {
 | 
			
		||||
                innerText: `Reader: ${reader._title.slice(0, 20)}`,
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              tag: "div",
 | 
			
		||||
              namespace: "html",
 | 
			
		||||
              directAttributes: {
 | 
			
		||||
              properties: {
 | 
			
		||||
                innerText: `itemID: ${reader.itemID}.`,
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              tag: "button",
 | 
			
		||||
              namespace: "html",
 | 
			
		||||
              directAttributes: {
 | 
			
		||||
              properties: {
 | 
			
		||||
                innerText: "Unregister",
 | 
			
		||||
              },
 | 
			
		||||
              listeners: [
 | 
			
		||||
 | 
			
		||||
@ -48,25 +48,15 @@ async function updatePrefsUI() {
 | 
			
		||||
  const renderLock = ztoolkit.getGlobal("Zotero").Promise.defer();
 | 
			
		||||
  const tableHelper = new ztoolkit.VirtualizedTabel(addon.data.prefs?.window!)
 | 
			
		||||
    .setContainerId(`${config.addonRef}-table-container`)
 | 
			
		||||
    // Add locale for table columns
 | 
			
		||||
    // Object.fromEntries is only available on firefox 62+,
 | 
			
		||||
    .setLocale(
 | 
			
		||||
      Array.from(
 | 
			
		||||
        new Map(
 | 
			
		||||
          addon.data.prefs?.columns.map((column) => [
 | 
			
		||||
            column.label,
 | 
			
		||||
            getString(column.label),
 | 
			
		||||
          ])
 | 
			
		||||
        )
 | 
			
		||||
      ).reduce((obj, [key, value]) => {
 | 
			
		||||
        obj[key] = value;
 | 
			
		||||
        return obj;
 | 
			
		||||
      }, {} as { [k: string]: string })
 | 
			
		||||
    )
 | 
			
		||||
    // id and getRowCount are required, others are optional.
 | 
			
		||||
    .setProp({
 | 
			
		||||
      id: `${config.addonRef}-prefs-table`,
 | 
			
		||||
      columns: addon.data.prefs?.columns,
 | 
			
		||||
      // 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,
 | 
			
		||||
        })
 | 
			
		||||
      ),
 | 
			
		||||
      showHeader: true,
 | 
			
		||||
      multiSelect: true,
 | 
			
		||||
      staticColumns: true,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user