From 2014a66c4948032ca2ee59e572875c68c058cc57 Mon Sep 17 00:00:00 2001
From: windingwind <33902321+windingwind@users.noreply.github.com>
Date: Fri, 29 Mar 2024 21:57:03 +0800
Subject: [PATCH] Add item pane API example
Fix pref pane API example
Use `onMainWindowLoad` and `onMainWindowUnload`
---
src-2.0/bootstrap.js | 14 +--
src-2.0/itemPaneSections.js | 96 +++++++++++++++++++
.../locale/en-US/make-it-red-preferences.ftl | 2 +
src-2.0/locale/en-US/make-it-red.ftl | 11 +++
src-2.0/make-it-red.js | 38 +++++---
src-2.0/preferencePanes.js | 10 ++
src-2.0/preferences.js | 1 +
src-2.0/preferences.xhtml | 18 ++++
8 files changed, 169 insertions(+), 21 deletions(-)
create mode 100644 src-2.0/itemPaneSections.js
create mode 100644 src-2.0/locale/en-US/make-it-red-preferences.ftl
create mode 100644 src-2.0/preferencePanes.js
create mode 100644 src-2.0/preferences.js
create mode 100644 src-2.0/preferences.xhtml
diff --git a/src-2.0/bootstrap.js b/src-2.0/bootstrap.js
index 0086658..675f892 100644
--- a/src-2.0/bootstrap.js
+++ b/src-2.0/bootstrap.js
@@ -11,18 +11,20 @@ function install() {
async function startup({ id, version, rootURI }) {
log("Starting");
- Zotero.PreferencePanes.register({
- pluginID: 'make-it-red@zotero.org',
- src: rootURI + 'preferences.xhtml',
- scripts: [rootURI + 'preferences.js']
- });
-
Services.scriptloader.loadSubScript(rootURI + 'make-it-red.js');
MakeItRed.init({ id, version, rootURI });
MakeItRed.addToAllWindows();
await MakeItRed.main();
}
+function onMainWindowLoad({ win }) {
+ MakeItRed.addToWindow(win);
+}
+
+function onMainWindowUnload(win) {
+ MakeItRed.removeFromWindow(win);
+}
+
function shutdown() {
log("Shutting down");
MakeItRed.removeFromAllWindows();
diff --git a/src-2.0/itemPaneSections.js b/src-2.0/itemPaneSections.js
new file mode 100644
index 0000000..3b21d29
--- /dev/null
+++ b/src-2.0/itemPaneSections.js
@@ -0,0 +1,96 @@
+(() => {
+ MakeItRed.registerItemPaneSections = function() {
+ // A minimal example
+ Zotero.ItemPaneManager.registerSection({
+ paneID: "example",
+ pluginID: this.id,
+ head: {
+ l10nID: "make-it-red-item-section-example1-head-text",
+ icon: "chrome://zotero/skin/16/universal/book.svg",
+ },
+ sidenav: {
+ l10nID: "make-it-red-item-section-example1-sidenav-tooltip",
+ icon: "chrome://zotero/skin/20/universal/save.svg",
+ },
+ onRender: ({ body, item, editable, tabType }) => {
+ body.textContent
+ = JSON.stringify({
+ id: item?.id,
+ editable,
+ tabType,
+ });
+ },
+ });
+
+ // A full example
+ Zotero.ItemPaneManager.registerSection({
+ paneID: "reader-example",
+ pluginID: this.id,
+ head: {
+ l10nID: "make-it-red-item-section-example2-head-text",
+ // Optional
+ l10nArgs: `{"status": "Initialized"}`,
+ // Can also have a optional dark icon
+ icon: "chrome://zotero/skin/16/universal/book.svg",
+ },
+ sidenav: {
+ l10nID: "make-it-red-item-section-example2-sidenav-tooltip",
+ icon: "chrome://zotero/skin/20/universal/save.svg",
+ },
+ // Optional
+ bodyXHTML: 'THIS IS TEST',
+ // Optional, Called when the section is first created, must be synchronous
+ onInit: ({ item }) => {
+ this.log("Section init!", item?.id);
+ },
+ // Optional, Called when the section is destroyed, must be synchronous
+ onDestroy: (props) => {
+ this.log("Section destroy!");
+ },
+ // Optional, Called when the section data changes (setting item/mode/tabType/inTrash), must be synchronous. return false to cancel the change
+ onItemChange: ({ item, setEnabled, tabType }) => {
+ this.log(`Section item data changed to ${item?.id}`);
+ setEnabled(tabType === "reader");
+ return true;
+ },
+ // Called when the section is asked to render, must be synchronous.
+ onRender: ({ body, item, setL10nArgs, setSectionSummary, setSectionButtonStatus }) => {
+ this.log("Section rendered!", item?.id);
+ let title = body.querySelector("#test");
+ title.style.color = "red";
+ title.textContent = "LOADING";
+ setL10nArgs(`{ "status": "Loading" }`);
+ setSectionSummary('loading!');
+ setSectionButtonStatus("test", { hidden: true });
+ },
+ // Optional, can be asynchronous.
+ onAsyncRender: async ({ body, item, setL10nArgs, setSectionSummary, setSectionButtonStatus }) => {
+ this.log("Section secondary render start!", item?.id);
+ await Zotero.Promise.delay(1000);
+ this.log("Section secondary render finish!", item?.id);
+ let title = body.querySelector("#test");
+ title.style.color = "green";
+ title.textContent = item.getField("title");
+ setL10nArgs(`{ "status": "Loaded" }`);
+ setSectionSummary('rendered!');
+ setSectionButtonStatus("test", { hidden: false });
+ },
+ // Optional, Called when the section is toggled. Can happen anytime even if the section is not visible or not rendered
+ onToggle: ({ item }) => {
+ this.log("Section toggled!", item?.id);
+ },
+ // Optional, Buttons to be shown in the section header
+ sectionButtons: [
+ {
+ type: "test",
+ icon: "chrome://zotero/skin/16/universal/empty-trash.svg",
+ l10nID: "make-it-red-item-section-example2-button-tooltip",
+ onClick: ({ item, paneID }) => {
+ this.log("Section clicked!", item?.id);
+ Zotero.ItemPaneManager.unregisterSection(paneID);
+ },
+ },
+ ],
+ });
+ }
+})();
diff --git a/src-2.0/locale/en-US/make-it-red-preferences.ftl b/src-2.0/locale/en-US/make-it-red-preferences.ftl
new file mode 100644
index 0000000..2d00d81
--- /dev/null
+++ b/src-2.0/locale/en-US/make-it-red-preferences.ftl
@@ -0,0 +1,2 @@
+make-it-red-title = Plugin Settings
+make-it-red-intensity = Intensity
diff --git a/src-2.0/locale/en-US/make-it-red.ftl b/src-2.0/locale/en-US/make-it-red.ftl
index 16ba6b3..ab67a4b 100644
--- a/src-2.0/locale/en-US/make-it-red.ftl
+++ b/src-2.0/locale/en-US/make-it-red.ftl
@@ -1,2 +1,13 @@
make-it-red-green-instead =
.label = Make It Green Instead
+
+make-it-red-item-section-example1-head-text =
+ .label = Make It Red: Item Info
+make-it-red-item-section-example1-sidenav-tooltip =
+ .tooltiptext = This is Make It Red section (item info)
+make-it-red-item-section-example2-head-text =
+ .label = Make It Red: Reader [{$status}]
+make-it-red-item-section-example2-sidenav-tooltip =
+ .tooltiptext = This is Make It Red section (reader)
+make-it-red-item-section-example2-button-tooltip =
+ .tooltiptext = Unregister this section
diff --git a/src-2.0/make-it-red.js b/src-2.0/make-it-red.js
index 0398a85..65d10db 100644
--- a/src-2.0/make-it-red.js
+++ b/src-2.0/make-it-red.js
@@ -18,6 +18,11 @@ MakeItRed = {
},
addToWindow(window) {
+ if (window._makeItRedAdded) {
+ return;
+ }
+ window._makeItRedAdded = true;
+
let doc = window.document;
// Add a stylesheet to the main Zotero pane
@@ -46,12 +51,7 @@ MakeItRed = {
},
addToAllWindows() {
- var enumerator = Services.wm.getEnumerator("navigator:browser");
- while (enumerator.hasMoreElements()) {
- let win = enumerator.getNext();
- if (!win.ZoteroPane) continue;
- this.addToWindow(win);
- }
+ Zotero.getMainWindows().forEach((win) => this.addToWindow(win));
},
storeAddedElement(elem) {
@@ -62,21 +62,21 @@ MakeItRed = {
},
removeFromWindow(window) {
- var doc = window.document;
+ if (!window._makeItRedAdded) {
+ return;
+ }
+ window._makeItRedAdded = false;
+
+ let doc = window.document;
// Remove all elements added to DOM
for (let id of this.addedElementIDs) {
doc.getElementById(id)?.remove();
}
- doc.querySelector('[href="make-it-red.ftl"]').remove();
+ doc.querySelector('[href="make-it-red.ftl"]')?.remove();
},
removeFromAllWindows() {
- var enumerator = Services.wm.getEnumerator("navigator:browser");
- while (enumerator.hasMoreElements()) {
- let win = enumerator.getNext();
- if (!win.ZoteroPane) continue;
- this.removeFromWindow(win);
- }
+ Zotero.getMainWindows().forEach((win) => this.removeFromWindow(win));
},
toggleGreen(window, enabled) {
@@ -86,10 +86,18 @@ MakeItRed = {
async main() {
// Global properties are included automatically in Zotero 7
- var host = new URL('https://foo.com/path').host;
+ let host = new URL('https://foo.com/path').host;
this.log(`Host is ${host}`);
// Retrieve a global pref
this.log(`Intensity is ${Zotero.Prefs.get('extensions.make-it-red.intensity', true)}`);
+
+ // Load sub scripts
+ Services.scriptloader.loadSubScript(this.rootURI + 'preferencePanes.js', this);
+ Services.scriptloader.loadSubScript(this.rootURI + 'itemPaneSections.js', this);
+
+ // Use Zotero plugin API to register stuff
+ this.registerPrefPanes();
+ this.registerItemPaneSections();
},
};
diff --git a/src-2.0/preferencePanes.js b/src-2.0/preferencePanes.js
new file mode 100644
index 0000000..9d95f09
--- /dev/null
+++ b/src-2.0/preferencePanes.js
@@ -0,0 +1,10 @@
+(() => {
+ MakeItRed.registerPrefPanes = function () {
+ Zotero.PreferencePanes.register({
+ pluginID: MakeItRed.id,
+ src: MakeItRed.rootURI + 'preferences.xhtml',
+ scripts: [MakeItRed.rootURI + 'preferences.js'],
+ label: "Make It Red",
+ })
+ }
+})();
diff --git a/src-2.0/preferences.js b/src-2.0/preferences.js
new file mode 100644
index 0000000..a84388a
--- /dev/null
+++ b/src-2.0/preferences.js
@@ -0,0 +1 @@
+Zotero.debug("Make It Red Pref Pane Loaded!");
diff --git a/src-2.0/preferences.xhtml b/src-2.0/preferences.xhtml
new file mode 100644
index 0000000..65511b7
--- /dev/null
+++ b/src-2.0/preferences.xhtml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+