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 @@ + + + + + + + + + + + +