diff --git a/README.md b/README.md
index 51a9405..731fbef 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,12 @@
This is an addon/plugin template for [Zotero](https://www.zotero.org/).
+[Documentation](https://zotero.yuque.com/books/share/8d230829-6004-4934-b4c6-685a7001bfa0/vec88d)(Chinese, provides English translation)
+
+> πYou are currently in `bootstrap` extension mode. To use `overlay` mode, plsase switch to `overlay` branch in git.
+
+> β οΈ`overlay` mode will no longer be supported in the coming Zotero 7. Please use the `bootstrap` extension mode instead. See discussion here: https://groups.google.com/g/zotero-dev/c/TT_rcLVpQwg
+
## Features
- TypeScript support;
@@ -49,7 +55,7 @@ This section shows the directory structure of a template.
```shell
β .gitignore
β .release-it.json # release-it conf
-| jsconfig.json # https://code.visualstudio.com/docs/languages/jsconfig#
+| tsconfig.json # https://code.visualstudio.com/docs/languages/jsconfig#
β build.js # esbuild
β LICENSE
β package.json # npm conf
@@ -61,10 +67,10 @@ This section shows the directory structure of a template.
ββaddon # addon dir
β β chrome.manifest #addon conf
β β install.rdf # addon install conf
+β β bootstrap.js # addon load/unload script, like a main.c
β β
β ββchrome
β ββcontent # UI
-β β β overlay.xul
β β β preferences.xul
β β β
β β ββscripts
@@ -152,6 +158,8 @@ You can also debug code in these ways:
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!
diff --git a/addon/bootstrap.js b/addon/bootstrap.js
new file mode 100644
index 0000000..a22fe5b
--- /dev/null
+++ b/addon/bootstrap.js
@@ -0,0 +1,71 @@
+/* Copyright 2012 Will Shanks.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+/* global Components, Services */
+/* global addon, APP_SHUTDOWN */
+const { classes: Cc, utils: Cu } = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
+
+function install(data, reason) {}
+
+function startup(data, reason) {
+ // Load the addon to Zotero if window is ready
+ const loadAddon = (window) => {
+ console.log(window);
+ if (window.document.readyState === "complete" && window.Zotero) {
+ Services.scriptloader.loadSubScript(
+ "chrome://__addonRef__/content/scripts/index.js"
+ );
+ } else {
+ window.addEventListener("load", (e) => {
+ if (window.Zotero) {
+ Services.scriptloader.loadSubScript(
+ "chrome://__addonRef__/content/scripts/index.js"
+ );
+ }
+ });
+ }
+ };
+
+ // Listen to windows
+ var WindowListener = {
+ onOpenWindow: function (xulWindow) {
+ loadAddon(
+ xulWindow
+ .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+ .getInterface(Components.interfaces.nsIDOMWindow)
+ );
+ },
+ };
+ Services.wm.addListener(WindowListener);
+
+ // Scan current windows
+ const windows = Services.wm.getEnumerator("navigator:browser");
+ while (windows.hasMoreElements()) {
+ loadAddon(
+ windows.getNext().QueryInterface(Components.interfaces.nsIDOMWindow)
+ );
+ }
+}
+
+function shutdown(data, reason) {
+ if (reason === APP_SHUTDOWN) {
+ return;
+ }
+ var _Zotero = Components.classes["@zotero.org/Zotero;1"].getService(
+ Components.interfaces.nsISupports
+ ).wrappedJSObject;
+ _Zotero.AddonTemplate.events.onUnInit(_Zotero);
+
+ Cc["@mozilla.org/intl/stringbundle;1"]
+ .getService(Components.interfaces.nsIStringBundleService)
+ .flushBundles();
+
+ Cu.unload("chrome://_addonRef__/scripts/index.js");
+}
+
+function uninstall(data, reason) {}
diff --git a/addon/chrome.manifest b/addon/chrome.manifest
index 59b2482..6c33bcd 100644
--- a/addon/chrome.manifest
+++ b/addon/chrome.manifest
@@ -2,6 +2,3 @@ content __addonRef__ chrome/content/
skin __addonRef__ default chrome/skin/default/__addonRef__/
locale __addonRef__ en-US chrome/locale/en-US/
locale __addonRef__ zh-CN chrome/locale/zh-CN/
-
-overlay chrome://zotero/content/zoteroPane.xul chrome://__addonRef__/content/overlay.xul
-overlay chrome://zotero/content/preferences/preferences.xul chrome://__addonRef__/content/preferences.xul
diff --git a/addon/chrome/content/overlay.xul b/addon/chrome/content/overlay.xul
deleted file mode 100644
index 08a0402..0000000
--- a/addon/chrome/content/overlay.xul
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/addon/chrome/content/preferences.xul b/addon/chrome/content/preferences.xul
index b3d219b..7f75ee3 100644
--- a/addon/chrome/content/preferences.xul
+++ b/addon/chrome/content/preferences.xul
@@ -1,14 +1,15 @@
-
+
-
+
+
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/addon/chrome/skin/default/plugintemplate/favicon.png b/addon/chrome/skin/default/addontemplate/favicon.png
similarity index 100%
rename from addon/chrome/skin/default/plugintemplate/favicon.png
rename to addon/chrome/skin/default/addontemplate/favicon.png
diff --git a/addon/chrome/skin/default/plugintemplate/favicon@0.5x.png b/addon/chrome/skin/default/addontemplate/favicon@0.5x.png
similarity index 100%
rename from addon/chrome/skin/default/plugintemplate/favicon@0.5x.png
rename to addon/chrome/skin/default/addontemplate/favicon@0.5x.png
diff --git a/addon/install.rdf b/addon/install.rdf
index 283efec..15fd8bf 100644
--- a/addon/install.rdf
+++ b/addon/install.rdf
@@ -13,7 +13,10 @@
em:description="__description__"
em:homepageURL="__homepage__"
em:iconURL="chrome://__addonRef__/skin/favicon.png"
- em:updateURL="__updaterdf__">>
+ em:optionsURL="chrome://__addonRef__/content/preferences.xul"
+ em:updateURL="__updaterdf__"
+ em:multiprocessCompatible="true"
+ em:bootstrap="true">>
2
diff --git a/build.js b/build.js
index 139637d..71578ae 100644
--- a/build.js
+++ b/build.js
@@ -115,6 +115,7 @@ async function main() {
path.join(buildDir, "**/*.xul"),
path.join(buildDir, "**/*.manifest"),
path.join(buildDir, "addon/defaults", "**/*.js"),
+ path.join(buildDir, "addon/bootstrap.js"),
"update.rdf",
],
from: [
diff --git a/package.json b/package.json
index 98f9a81..1097aaf 100644
--- a/package.json
+++ b/package.json
@@ -34,6 +34,6 @@
},
"devDependencies": {
"release-it": "^14.14.0",
- "zotero-types": "^0.0.3"
+ "zotero-types": "^0.0.4"
}
}
diff --git a/src/events.ts b/src/events.ts
index f64721d..322b174 100644
--- a/src/events.ts
+++ b/src/events.ts
@@ -27,30 +27,32 @@ class AddonEvents extends AddonModule {
};
}
- public async onInit() {
+ public async onInit(_Zotero) {
// This function is the setup code of the addon
- Zotero.debug(`${addonName}: init called`);
+ console.log(`${addonName}: init called`);
+ _Zotero.debug(`${addonName}: init called`);
+ // alert(112233);
// Reset prefs
this.resetState();
// Register the callback in Zotero as an item observer
- let notifierID = Zotero.Notifier.registerObserver(this.notifierCallback, [
+ let notifierID = _Zotero.Notifier.registerObserver(this.notifierCallback, [
"tab",
"item",
"file",
]);
// Unregister callback when the window closes (important to avoid a memory leak)
- window.addEventListener(
+ _Zotero.getMainWindow().addEventListener(
"unload",
function (e) {
- Zotero.Notifier.unregisterObserver(notifierID);
+ _Zotero.Notifier.unregisterObserver(notifierID);
},
false
);
- this._Addon.views.initViews();
+ this._Addon.views.initViews(_Zotero);
}
private resetState(): void {
@@ -65,6 +67,15 @@ class AddonEvents extends AddonModule {
// Zotero.Prefs.set("addonTemplate.testPref", true);
// }
}
+
+ public onUnInit(_Zotero): void {
+ console.log(`${addonName}: uninit called`);
+ _Zotero.debug(`${addonName}: uninit called`);
+ // Remove elements and do clean up
+ this._Addon.views.unInitViews(_Zotero);
+ // Remove addon object
+ _Zotero.AddonTemplate = undefined;
+ }
}
export default AddonEvents;
diff --git a/src/index.ts b/src/index.ts
index c631564..87f6363 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,11 +1,9 @@
import { Addon } from "./addon";
-Zotero.AddonTemplate = new Addon();
-
-window.addEventListener(
- "load",
- async function (e) {
- Zotero.AddonTemplate.events.onInit();
- },
- false
-);
+var _Zotero = Components.classes["@zotero.org/Zotero;1"].getService(
+ Components.interfaces.nsISupports
+).wrappedJSObject;
+if (!_Zotero.AddonTemplate) {
+ _Zotero.AddonTemplate = new Addon();
+ _Zotero.AddonTemplate.events.onInit(_Zotero);
+}
diff --git a/src/views.ts b/src/views.ts
index 0c9928c..df36171 100644
--- a/src/views.ts
+++ b/src/views.ts
@@ -16,9 +16,27 @@ class AddonViews extends AddonModule {
};
}
- public initViews() {
+ public initViews(_Zotero) {
// You can init the UI elements that
// cannot be initialized with overlay.xul
+ console.log("Initializing UI");
+ const _window: Window = _Zotero.getMainWindow();
+ const menuitem = _window.document.createElement("menuitem");
+ menuitem.id = "zotero-itemmenu-addontemplate-test";
+ menuitem.setAttribute("label", "Addon Template");
+ menuitem.setAttribute("oncommand", "alert('Hello World!')");
+ menuitem.className = "menuitem-iconic";
+ menuitem.style["list-style-image"] =
+ "url('chrome://addontemplate/skin/favicon@0.5x.png')";
+ _window.document.querySelector("#zotero-itemmenu").appendChild(menuitem);
+ }
+
+ public unInitViews(_Zotero) {
+ console.log("Uninitializing UI");
+ const _window: Window = _Zotero.getMainWindow();
+ _window.document
+ .querySelector("#zotero-itemmenu-addontemplate-test")
+ ?.remove();
}
public showProgressWindow(
diff --git a/update.rdf b/update.rdf
index c237fc1..2647efc 100644
--- a/update.rdf
+++ b/update.rdf
@@ -11,7 +11,7 @@
zotero@chnm.gmu.edu
5.0
*
- __releasepage__
+ https://github.com/windingwind/zotero-addon-template/releases/latest/download/zotero-addon-template.xpi
@@ -19,7 +19,7 @@
juris-m@juris-m.github.io
5.0
*
- __releasepage__
+ https://github.com/windingwind/zotero-addon-template/releases/latest/download/zotero-addon-template.xpi