update: toolkit 1.0.4

This commit is contained in:
xiangyu 2023-01-12 16:41:03 +08:00
parent 4524527867
commit 8025496b44
4 changed files with 28 additions and 34 deletions

View File

@ -92,7 +92,7 @@ See how the examples work by directly downloading the `xpi` file from GitHub rel
This is also how your plugin will be released and used by others. 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 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. > The `xpi` package is a zip file. However, please don't modify it directly. Modify the source code and build it.
### Build from Source ### Build from Source
@ -129,6 +129,7 @@ This is also how your plugin will be released and used by others.
### Release ### Release
To build and release, use To build and release, use
```shell ```shell
# A release-it command: version increase, npm run build, git push, and GitHub release # 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 # You need to set the environment variable GITHUB_TOKEN https://github.com/settings/tokens
@ -246,14 +247,18 @@ 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`: 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. - 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`. Using `createElement`, it switches API depending on the current platform automatically. - 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 ### About Build
Use esbuild to build `.ts` source code to `.js`. 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`). Use `replace-in-file` to replace keywords and configurations defined in `package.json` in non-build files (`.xul/xhtml`, `.dtd`, and `.properties`).

View File

@ -35,7 +35,7 @@
}, },
"homepage": "https://github.com/windingwind/zotero-addon-template#readme", "homepage": "https://github.com/windingwind/zotero-addon-template#readme",
"dependencies": { "dependencies": {
"zotero-plugin-toolkit": "^1.0.3" "zotero-plugin-toolkit": "^1.0.4"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^18.11.17", "@types/node": "^18.11.17",

View File

@ -15,7 +15,7 @@ if (!basicTool.getGlobal("Zotero").AddonTemplate) {
_globalThis.ztoolkit = addon.data.ztoolkit; _globalThis.ztoolkit = addon.data.ztoolkit;
ztoolkit.basicOptions.log.prefix = `[${config.addonName}]`; ztoolkit.basicOptions.log.prefix = `[${config.addonName}]`;
ztoolkit.basicOptions.log.disableConsole = addon.data.env === "production"; ztoolkit.basicOptions.log.disableConsole = addon.data.env === "production";
ztoolkit.UI.elementOptions.enableElementJSONLog = ztoolkit.UI.basicOptions.ui.enableElementJSONLog =
addon.data.env === "development"; addon.data.env === "development";
Zotero.AddonTemplate = addon; Zotero.AddonTemplate = addon;
// Trigger addon hook for initialization // Trigger addon hook for initialization

View File

@ -184,14 +184,13 @@ export class KeyExampleFactory {
export class UIExampleFactory { export class UIExampleFactory {
@example @example
static registerStyleSheet() { static registerStyleSheet() {
const styles = ztoolkit.UI.creatElementsFromJSON(document, { const styles = ztoolkit.UI.createElement(document, "link", {
tag: "link", properties: {
directAttributes: {
type: "text/css", type: "text/css",
rel: "stylesheet", rel: "stylesheet",
href: `chrome://${config.addonRef}/content/zoteroPane.css`, href: `chrome://${config.addonRef}/content/zoteroPane.css`,
}, },
}) as HTMLLinkElement; });
document.documentElement.appendChild(styles); document.documentElement.appendChild(styles);
document document
.getElementById("zotero-item-pane-content") .getElementById("zotero-item-pane-content")
@ -218,7 +217,7 @@ export class UIExampleFactory {
{ {
tag: "menu", tag: "menu",
label: getString("menupopup.label"), label: getString("menupopup.label"),
subElementOptions: [ children: [
{ {
tag: "menuitem", tag: "menuitem",
label: getString("menuitem.submenulabel"), label: getString("menuitem.submenulabel"),
@ -313,28 +312,24 @@ export class UIExampleFactory {
const tabId = ztoolkit.LibraryTabPanel.register( const tabId = ztoolkit.LibraryTabPanel.register(
getString("tabpanel.lib.tab.label"), getString("tabpanel.lib.tab.label"),
(panel: XUL.Element, win: Window) => { (panel: XUL.Element, win: Window) => {
const elem = ztoolkit.UI.creatElementsFromJSON(win.document, { const elem = ztoolkit.UI.createElement(win.document, "vbox", {
tag: "vbox", children: [
namespace: "xul",
subElementOptions: [
{ {
tag: "h2", tag: "h2",
namespace: "html", properties: {
directAttributes: {
innerText: "Hello World!", innerText: "Hello World!",
}, },
}, },
{ {
tag: "div", tag: "div",
namespace: "html", properties: {
directAttributes: {
innerText: "This is a library tab.", innerText: "This is a library tab.",
}, },
}, },
{ {
tag: "button", tag: "button",
namespace: "html", namespace: "html",
directAttributes: { properties: {
innerText: "Unregister", innerText: "Unregister",
}, },
listeners: [ listeners: [
@ -373,46 +368,40 @@ export class UIExampleFactory {
return; return;
} }
ztoolkit.log(reader); ztoolkit.log(reader);
const elem = ztoolkit.UI.creatElementsFromJSON(win.document, { const elem = ztoolkit.UI.createElement(win.document, "vbox", {
tag: "vbox",
id: `${config.addonRef}-${reader._instanceID}-extra-reader-tab-div`, id: `${config.addonRef}-${reader._instanceID}-extra-reader-tab-div`,
namespace: "xul",
// This is important! Don't create content for multiple times // This is important! Don't create content for multiple times
// ignoreIfExists: true, // ignoreIfExists: true,
removeIfExists: true, removeIfExists: true,
subElementOptions: [ children: [
{ {
tag: "h2", tag: "h2",
namespace: "html", properties: {
directAttributes: {
innerText: "Hello World!", innerText: "Hello World!",
}, },
}, },
{ {
tag: "div", tag: "div",
namespace: "html", properties: {
directAttributes: {
innerText: "This is a reader tab.", innerText: "This is a reader tab.",
}, },
}, },
{ {
tag: "div", tag: "div",
namespace: "html", properties: {
directAttributes: {
innerText: `Reader: ${reader._title.slice(0, 20)}`, innerText: `Reader: ${reader._title.slice(0, 20)}`,
}, },
}, },
{ {
tag: "div", tag: "div",
namespace: "html", properties: {
directAttributes: {
innerText: `itemID: ${reader.itemID}.`, innerText: `itemID: ${reader.itemID}.`,
}, },
}, },
{ {
tag: "button", tag: "button",
namespace: "html", namespace: "html",
directAttributes: { properties: {
innerText: "Unregister", innerText: "Unregister",
}, },
listeners: [ listeners: [