From d6cb58c3e721610d9ffba82fe3b9bce9f20b7e71 Mon Sep 17 00:00:00 2001 From: windingwind <33902321+windingwind@users.noreply.github.com> Date: Thu, 2 Nov 2023 20:04:04 +0800 Subject: [PATCH] chore: use Zotero.Reader.registerEventListener --- package.json | 2 +- src/hooks.ts | 19 +--- src/modules/reader.ts | 197 +++++++++++++----------------------------- src/utils/ztoolkit.ts | 3 - typings/global.d.ts | 2 - 5 files changed, 62 insertions(+), 161 deletions(-) diff --git a/package.json b/package.json index 123a90b..3fb731f 100644 --- a/package.json +++ b/package.json @@ -98,6 +98,6 @@ "release-it": "^16.1.5", "replace-in-file": "^7.0.1", "typescript": "^5.2.2", - "zotero-types": "^1.3.2" + "zotero-types": "^1.3.5" } } diff --git a/src/hooks.ts b/src/hooks.ts index 4801523..bb268e3 100644 --- a/src/hooks.ts +++ b/src/hooks.ts @@ -26,9 +26,7 @@ import { import { registerNotify } from "./modules/notify"; import { showWorkspaceWindow } from "./modules/workspace/window"; import { - checkReaderAnnotationButton, - registerReaderInitializer, - unregisterReaderInitializer, + registerReaderAnnotationButton, } from "./modules/reader"; import { setSyncing, callSyncing } from "./modules/sync/hooks"; import { @@ -70,6 +68,8 @@ async function onStartup() { registerPrefsWindow(); + registerReaderAnnotationButton(); + initSyncList(); setSyncing(); @@ -88,19 +88,15 @@ async function onMainWindowLoad(win: Window): Promise { registerWorkspaceTab(); - registerReaderInitializer(); - initTemplates(); } async function onMainWindowUnload(win: Window): Promise { ztoolkit.unregisterAll(); - unregisterReaderInitializer(); } function onShutdown(): void { ztoolkit.unregisterAll(); - unregisterReaderInitializer(); // Remove addon object addon.data.alive = false; unregisterWorkspaceTab(); @@ -150,15 +146,6 @@ function onNotify( }); } } - // Reader annotation buttons update - if (event === "add" && type === "item") { - const annotationItems = Zotero.Items.get(ids as number[]).filter((item) => - item.isAnnotation(), - ); - if (annotationItems.length !== 0) { - checkReaderAnnotationButton(annotationItems); - } - } // Insert annotation when assigning tag starts with @ if (event === "add" && type === "item-tag") { annotationTagAction(ids as number[], extraData); diff --git a/src/modules/reader.ts b/src/modules/reader.ts index b98f2e3..42d9a9b 100644 --- a/src/modules/reader.ts +++ b/src/modules/reader.ts @@ -1,153 +1,72 @@ -import { TagElementProps } from "zotero-plugin-toolkit/dist/tools/ui"; import { config } from "../../package.json"; import { ICONS } from "../utils/config"; import { getNoteLink, getNoteLinkParams } from "../utils/link"; import { addLineToNote } from "../utils/note"; -export function registerReaderInitializer() { - ztoolkit.ReaderInstance.register( - "initialized", - `${config.addonRef}-annotationButtons`, - initializeReaderAnnotationButton, +export function registerReaderAnnotationButton() { + Zotero.Reader.registerEventListener( + "renderSidebarAnnotationHeader", + (event) => { + const { doc, append, params } = event; + const annotationData = params.annotation; + const annotationItem = Zotero.Items.getByLibraryAndKey( + annotationData.libraryID, + annotationData.id, + ) as Zotero.Item; + + if (!annotationItem) { + return; + } + const itemID = annotationItem.id; + append( + ztoolkit.UI.createElement(doc, "div", { + tag: "div", + classList: ["icon"], + properties: { + innerHTML: ICONS.readerQuickNote, + }, + listeners: [ + { + type: "click", + listener: (e) => { + createNoteFromAnnotation( + itemID, + (e as MouseEvent).shiftKey ? "standalone" : "auto", + ); + e.preventDefault(); + }, + }, + { + type: "mouseover", + listener: (e) => { + (e.target as HTMLElement).style.backgroundColor = "#F0F0F0"; + }, + }, + { + type: "mouseout", + listener: (e) => { + (e.target as HTMLElement).style.removeProperty( + "background-color", + ); + }, + }, + ], + enableElementRecord: true, + }), + ); + }, + config.addonID, ); - // Force re-initialize - Zotero.Reader._readers.forEach((r) => { - initializeReaderAnnotationButton(r); - }); -} - -export function unregisterReaderInitializer() { - Zotero.Reader._readers.forEach((r) => { - unInitializeReaderAnnotationButton(r); - }); -} - -export async function checkReaderAnnotationButton(items: Zotero.Item[]) { - const hitSet = new Set(); - let t = 0; - const period = 100; - const wait = 5000; - while (items.length > hitSet.size && t < wait) { - for (const instance of Zotero.Reader._readers) { - const hitItems = await initializeReaderAnnotationButton(instance); - hitItems.forEach((item) => hitSet.add(item.id)); - } - await Zotero.Promise.delay(period); - t += period; - } -} - -async function initializeReaderAnnotationButton( - instance: _ZoteroTypes.ReaderInstance, -): Promise { - if (!instance) { - return []; - } - await instance._initPromise; - await instance._waitForReader(); - const _document = instance._iframeWindow?.document; - if (!_document) { - return []; - } - const hitItems: Zotero.Item[] = []; - for (const moreButton of Array.from(_document.querySelectorAll(".more"))) { - if (moreButton.getAttribute("_betternotesInitialized") === "true") { - continue; - } - moreButton.setAttribute("_betternotesInitialized", "true"); - - let annotationWrapper = moreButton; - while (!annotationWrapper.getAttribute("data-sidebar-annotation-id")) { - annotationWrapper = annotationWrapper.parentElement!; - } - const itemKey = - annotationWrapper.getAttribute("data-sidebar-annotation-id") || ""; - if (!instance.itemID) { - continue; - } - const libraryID = Zotero.Items.get(instance.itemID).libraryID; - const annotationItem = (await Zotero.Items.getByLibraryAndKeyAsync( - libraryID, - itemKey, - )) as Zotero.Item; - - if (!annotationItem) { - continue; - } - - hitItems.push(annotationItem); - - const annotationButtons: TagElementProps[] = [ - { - tag: "div", - classList: ["icon"], - properties: { - innerHTML: ICONS.readerQuickNote, - }, - listeners: [ - { - type: "click", - listener: (e) => { - createNoteFromAnnotation( - annotationItem, - (e as MouseEvent).shiftKey ? "standalone" : "auto", - ); - e.preventDefault(); - }, - }, - { - type: "mouseover", - listener: (e) => { - (e.target as HTMLElement).style.backgroundColor = "#F0F0F0"; - }, - }, - { - type: "mouseout", - listener: (e) => { - (e.target as HTMLElement).style.removeProperty( - "background-color", - ); - }, - }, - ], - enableElementRecord: true, - }, - ]; - - ztoolkit.UI.insertElementBefore( - { - tag: "fragment", - children: annotationButtons, - }, - moreButton, - ); - } - return hitItems; -} - -async function unInitializeReaderAnnotationButton( - instance: _ZoteroTypes.ReaderInstance, -): Promise { - if (!instance) { - return; - } - await instance._initPromise; - await instance._waitForReader(); - const _document = instance._iframeWindow?.document; - if (!_document) { - return; - } - for (const moreButton of Array.from(_document.querySelectorAll(".more"))) { - if (moreButton.getAttribute("_betternotesInitialized") === "true") { - moreButton.removeAttribute("_betternotesInitialized"); - } - } } async function createNoteFromAnnotation( - annotationItem: Zotero.Item, + itemID: number, openMode: "standalone" | "auto" = "auto", ) { + const annotationItem = Zotero.Items.get(itemID); + if (!annotationItem) { + return; + } const annotationTags = annotationItem.getTags().map((_) => _.tag); const linkRegex = new RegExp("^zotero://note/(.*)$"); for (const tag of annotationTags) { diff --git a/src/utils/ztoolkit.ts b/src/utils/ztoolkit.ts index e995e06..1587323 100644 --- a/src/utils/ztoolkit.ts +++ b/src/utils/ztoolkit.ts @@ -38,7 +38,6 @@ import { VirtualizedTableHelper } from "zotero-plugin-toolkit/dist/helpers/virtu import { LibraryTabPanelManager } from "zotero-plugin-toolkit/dist/managers/libraryTabPanel"; import { MenuManager } from "zotero-plugin-toolkit/dist/managers/menu"; import { PromptManager } from "zotero-plugin-toolkit/dist/managers/prompt"; -import { ReaderInstanceManager } from "zotero-plugin-toolkit/dist/managers/readerInstance"; import { ReaderTabPanelManager } from "zotero-plugin-toolkit/dist/managers/readerTabPanel"; import { LargePrefHelper } from "zotero-plugin-toolkit/dist/helpers/largePref"; @@ -47,7 +46,6 @@ class MyToolkit extends BasicTool { Prompt: PromptManager; LibraryTabPanel: LibraryTabPanelManager; ReaderTabPanel: ReaderTabPanelManager; - ReaderInstance: ReaderInstanceManager; Menu: MenuManager; PreferencePane: PreferencePaneManager; Clipboard: typeof ClipboardHelper; @@ -63,7 +61,6 @@ class MyToolkit extends BasicTool { this.Prompt = new PromptManager(this); this.LibraryTabPanel = new LibraryTabPanelManager(this); this.ReaderTabPanel = new ReaderTabPanelManager(this); - this.ReaderInstance = new ReaderInstanceManager(this); this.Menu = new MenuManager(this); this.PreferencePane = new PreferencePaneManager(this); this.Clipboard = ClipboardHelper; diff --git a/typings/global.d.ts b/typings/global.d.ts index e9e395c..0cae16c 100644 --- a/typings/global.d.ts +++ b/typings/global.d.ts @@ -32,6 +32,4 @@ declare const addon: import("../src/addon").default; declare const __env__: "production" | "development"; -declare const ChromeUtils: any; - declare class Localization {}