import * as React from "react"; //#region src/basic.d.ts /** * Basic APIs with Zotero 6 & newer (7) compatibility. * See also https://www.zotero.org/support/dev/zotero_7_for_developers */ declare class BasicTool { /** * configurations. */ protected _basicOptions: BasicOptions; protected _console?: Console; static _version: string; /** * Get version - checks subclass first, then falls back to parent */ get _version(): string; get basicOptions(): BasicOptions; /** * * @param data Pass an BasicTool instance to copy its options. */ constructor(data?: BasicTool | BasicOptions); /** * @alpha * @param k */ getGlobal(k: "Zotero" | "zotero"): _ZoteroTypes.Zotero; /** * @alpha * @param k */ getGlobal(k: "ZoteroPane" | "ZoteroPane_Local"): _ZoteroTypes.ZoteroPane; /** * @alpha * @param k */ getGlobal(k: "Zotero_Tabs"): _ZoteroTypes.Zotero_Tabs; /** * @alpha * @param k */ getGlobal(k: "Zotero_File_Interface"): any; /** * @alpha * @param k */ getGlobal(k: "Zotero_File_Exporter"): any; /** * @alpha * @param k */ getGlobal(k: "Zotero_LocateMenu"): any; /** * @alpha * @param k */ getGlobal(k: "Zotero_Report_Interface"): any; /** * @alpha * @param k */ getGlobal(k: "Zotero_Timeline_Interface"): any; /** * @alpha * @param k */ getGlobal(k: "Zotero_Tooltip"): any; /** * @alpha * @param k */ getGlobal(k: "ZoteroContextPane"): _ZoteroTypes.ZoteroContextPane; /** * @alpha * @param k */ getGlobal(k: "ZoteroItemPane"): any; /** * @alpha * @param k */ getGlobal(k: K): GLOBAL[K]; /** * Get global variables. * @param k Global variable name, `Zotero`, `ZoteroPane`, `window`, `document`, etc. */ getGlobal(k: string): any; /** * If it's an XUL element * @param elem */ isXULElement(elem: Element): boolean; /** * Create an XUL element * * For Zotero 6, use `createElementNS`; * * For Zotero 7+, use `createXULElement`. * @param doc * @param type * @example * Create a ``: * ```ts * const compat = new ZoteroCompat(); * const doc = compat.getWindow().document; * const elem = compat.createXULElement(doc, "menuitem"); * ``` */ createXULElement(doc: Document, type: string): XULElement; /** * Output to both Zotero.debug and console.log * @param data e.g. string, number, object, ... */ log(...data: any): void; /** * Add a Zotero event listener callback * @param type Event type * @param callback Event callback */ addListenerCallback(type: T, callback: ListenerCallbackMap[T]): void; /** * Remove a Zotero event listener callback * @param type Event type * @param callback Event callback */ removeListenerCallback(type: T, callback: ListenerCallbackMap[T]): void; /** * Remove all Zotero event listener callbacks when the last callback is removed. */ protected _ensureRemoveListener(): void; /** * Ensure the main window listener is registered. */ protected _ensureMainWindowListener(): void; /** * Ensure the plugin listener is registered. */ protected _ensurePluginListener(): void; updateOptions(source?: BasicTool | BasicOptions): this; static getZotero(): _ZoteroTypes.Zotero; } interface BasicOptions { log: { readonly _type: "toolkitlog"; disableConsole: boolean; disableZLog: boolean; prefix: string; }; debug: { disableDebugBridgePassword: boolean; password: string; }; _debug?: BasicOptions["debug"]; api: { pluginID: string; }; listeners: { _mainWindow?: any; _plugin?: _ZoteroTypes.Plugins.observer; callbacks: { [K in keyof ListenerCallbackMap]: Set }; }; } declare abstract class ManagerTool extends BasicTool { abstract register(...data: any[]): any; abstract unregister(...data: any[]): any; /** * Unregister everything */ abstract unregisterAll(): any; protected _ensureAutoUnregisterAll(): void; } declare function unregister(tools: { [key: string | number]: any; }): void; declare function makeHelperTool(cls: T, options: BasicTool | BasicOptions): T; declare function makeHelperTool(cls: T, options: BasicTool | BasicOptions): T; declare function _importESModule(path: string): any; declare interface ListenerCallbackMap { onMainWindowLoad: (win: Window) => void; onMainWindowUnload: (win: Window) => void; onPluginUnload: (...args: Parameters>) => void; } declare class HelperTool { constructor(...args: any); updateOptions: BasicTool["updateOptions"]; } //#endregion //#region src/helpers/clipboard.d.ts /** * Copy helper for text/richtext/image. * * @example * Copy plain text * ```ts * new ClipboardHelper().addText("plain", "text/unicode").copy(); * ``` * @example * Copy plain text & rich text * ```ts * new ClipboardHelper().addText("plain", "text/unicode") * .addText("

rich text

", "text/html") * .copy(); * ``` * @example * Copy plain text, rich text & image * ```ts * new ClipboardHelper().addText("plain", "text/unicode") * .addText("

rich text

", "text/html") * .addImage("data:image/png;base64,...") * .copy(); * ``` */ declare class ClipboardHelper extends BasicTool { private transferable; private clipboardService; private filePath; constructor(); addText(source: string, type?: "text/html" | "text/plain" | "text/unicode"): this; addImage(source: string): this; addFile(path: string): this; copy(): this; } //#endregion //#region src/tools/ui.d.ts /** * UI APIs. Create elements and manage them. */ declare class UITool extends BasicTool { /** * UITool options */ protected _basicOptions: UIOptions; get basicOptions(): UIOptions; /** * Store elements created with this instance * * @remarks * > What is this for? * * In bootstrap plugins, elements must be manually maintained and removed on exiting. * * This API does this for you. */ protected elementCache: WeakRef[]; constructor(base?: BasicTool | BasicOptions); /** * Remove all elements created by `createElement`. * * @remarks * > What is this for? * * In bootstrap plugins, elements must be manually maintained and removed on exiting. * * This API does this for you. */ unregisterAll(): void; /** * Create `DocumentFragment`. * @param doc * @param tagName * @param props * @example * ```ts * const frag: DocumentFragment = ui.createElement( * document, "fragment", * { * children: * [ * { tag: "h1", properties: { innerText: "Hello World!" } } * ] * } * ); * ``` */ createElement(doc: Document, tagName: "fragment", props?: FragmentElementProps): DocumentFragment; /** * Create `HTMLElement`. * @param doc * @param tagName * @param props See {@link ElementProps } * @example * ```ts * const div: HTMLDivElement = ui.createElement(document, "div"); * ``` * @example * Attributes(for `elem.setAttribute()`), properties(for `elem.prop=`), listeners, and children. * ```ts * const div: HTMLDivElement = ui.createElement( * document, "div", * { * id: "hi-div", * skipIfExists: true, * listeners: * [ * { type: "click", listener: (e)=>ui.log("Clicked!") } * ], * children: * [ * { tag: "h1", properties: { innerText: "Hello World!" } }, * { tag: "a", attributes: { href: "https://www.zotero.org" } }, * ] * } * ); * ``` */ createElement(doc: Document, tagName: HTML_TAG, props?: HTMLElementProps): T; /** * Create `XULElement`. * @see ElementProps * @param doc * @param tagName * @param props See {@link ElementProps } * @example * ```ts * const menuitem: XULMenuItem = ui.createElement(document, "menuitem", { attributes: { label: "Click Me!" } }); * ``` */ createElement(doc: Document, tagName: XUL_TAG, props?: XULElementProps): T; /** * Create `SVGElement` * @param doc * @param tagName * @param props See {@link ElementProps } */ createElement(doc: Document, tagName: SVG_TAG, props?: SVGElementProps): T; /** * Create Element * @param doc * @param tagName * @param props See {@link ElementProps } */ createElement(doc: Document, tagName: string, props?: ElementProps): HTMLElement | XULElement | SVGElement; /** * @deprecated * @param doc target document, e.g. Zotero main window.document * @param tagName element tag name, e.g. `hbox`, `div` * @param namespace default "html" * @param enableElementRecord If current element will be recorded and maintained by toolkit. If not set, use this.enableElementRecordGlobal */ createElement(doc: Document, tagName: string, namespace?: "html" | "svg" | "xul", enableElementRecord?: boolean): HTMLElement | XULElement | SVGElement | DocumentFragment; /** * Append element(s) to a node. * @param properties See {@link ElementProps} * @param container The parent node to append to. * @returns A Node that is the appended child (aChild), * except when aChild is a DocumentFragment, * in which case the empty DocumentFragment is returned. */ appendElement(properties: TagElementProps, container: Element): Node; /** * Inserts a node before a reference node as a child of its parent node. * @param properties See {@link ElementProps} * @param referenceNode The node before which newNode is inserted. * @returns Node */ insertElementBefore(properties: TagElementProps, referenceNode: Element): Node | undefined; /** * Replace oldNode with a new one. * @param properties See {@link ElementProps} * @param oldNode The child to be replaced. * @returns The replaced Node. This is the same node as oldChild. */ replaceElement(properties: ElementProps & { tag: string; }, oldNode: Element): Node | undefined; /** * Parse XHTML to XUL fragment. For Zotero 6. * * To load preferences from a Zotero 7's `.xhtml`, use this method to parse it. * @param str xhtml raw text * @param entities dtd file list ("chrome://xxx.dtd") * @param defaultXUL true for default XUL namespace */ parseXHTMLToFragment(str: string, entities?: string[], defaultXUL?: boolean): DocumentFragment; } interface UIOptions extends BasicOptions { ui: { /** * Whether to record elements created with `createElement`. */ enableElementRecord: boolean; /** * Wether to log the `ElementProps` parameter in `createElement`. */ enableElementJSONLog: boolean; /** * Wether to log the DOM node mounted by `createElement`. */ enableElementDOMLog: boolean; }; } /** * `props` of `UITool.createElement`. See {@link UITool} */ interface ElementProps { /** * tagName */ tag?: string; /** * id */ id?: string; /** * xul | html | svg */ namespace?: string; /** * classList */ classList?: Array; /** * styles */ styles?: Partial; /** * Set with `elem.prop =` */ properties?: { [key: string]: unknown; }; /** * @deprecated Use `properties` */ directAttributes?: { [key: string]: string | boolean | number | null | undefined; }; /** * Set with `elem.setAttribute()` */ attributes?: { [key: string]: string | boolean | number | null | undefined; }; /** * Event listeners */ listeners?: Array<{ type: string; listener: EventListenerOrEventListenerObject | ((e: Event) => void) | null | undefined; options?: boolean | AddEventListenerOptions; }>; /** * Child elements. Will be created and appended to this element. */ children?: Array; /** * Set true to check if the element exists using `id`. If exists, return this element and do not do anything. */ ignoreIfExists?: boolean; /** * Set true to check if the element exists using `id`. If exists, skip element creation and continue with props/attrs/children. */ skipIfExists?: boolean; /** * Set true to check if the element exists using `id`. If exists, remove and re-create it, then continue with props/attrs/children. */ removeIfExists?: boolean; /** * Existence check will be processed under this element, default `document` */ checkExistenceParent?: HTMLElement; /** * Custom check hook. If it returns false, return undefined and do not do anything. * @param doc * @param options */ customCheck?: (doc: Document, options: ElementProps) => boolean; /** * @deprecated Use `children` */ subElementOptions?: Array; /** * Enable elements to be recorded by the toolkit so it can be removed when calling `unregisterAll`. */ enableElementRecord?: boolean; /** * Enable elements to be printed to console & Zotero.debug. */ enableElementJSONLog?: boolean; /** * Enable elements to be printed to console & Zotero.debug. */ enableElementDOMLog?: boolean; } interface TagElementProps extends ElementProps { tag: string; } interface HTMLElementProps extends Exclude { namespace?: "html"; } interface SVGElementProps extends Exclude { namespace?: "svg"; } interface XULElementProps extends Exclude { namespace?: "xul"; } interface FragmentElementProps { children?: Array; } interface XULElementTagNameMap { action: XULElement; arrowscrollbox: XULElement; bbox: XULBoxElement; binding: XULElement; bindings: XULElement; box: XULElement; broadcaster: XULElement; broadcasterset: XULElement; button: XULButtonElement; browser: XULBrowserElement; checkbox: XULCheckboxElement; caption: XULElement; colorpicker: XULColorPickerElement; column: XULElement; columns: XULElement; commandset: XULElement; command: XULCommandElement; conditions: XULElement; content: XULElement; deck: XULDeckElement; description: XULDescriptionElement; dialog: XULElement; dialogheader: XULElement; editor: XULElement; grid: XULElement; grippy: XULGrippyElement; groupbox: XULGroupBoxElement; hbox: XULBoxElement; iframe: XULElement; image: XULElement; key: XULElement; keyset: XULElement; label: XULLabelElement; listbox: XULElement; listcell: XULElement; listcol: XULElement; listcols: XULElement; listhead: XULElement; listheader: XULElement; listitem: XULListItemElement; member: XULElement; menu: XULMenuElement; menubar: XULMenuBarElement; menuitem: XULMenuItemElement; menulist: XULMenuListElement; menupopup: XULMenuPopupElement; menuseparator: XULMenuSeparatorElement; observes: XULElement; overlay: XULElement; page: XULElement; popup: XULPopupElement; popupset: XULElement; preference: XULElement; preferences: XULElement; prefpane: XULElement; prefwindow: XULElement; progressmeter: XULProgressMeterElement; radio: XULRadioElement; radiogroup: XULRadioGroupElement; resizer: XULElement; richlistbox: XULElement; richlistitem: XULElement; row: XULElement; rows: XULElement; rule: XULElement; script: XULElement; scrollbar: XULScrollBarElement; scrollbox: XULElement; scrollcorner: XULElement; separator: XULSeparatorElement; spacer: XULSpacerElement; splitter: XULSplitterElement; stack: XULElement; statusbar: XULStatusBarElement; statusbarpanel: XULStatusBarPanelElement; stringbundle: XULElement; stringbundleset: XULElement; tab: XULTabElement; tabbrowser: XULElement; tabbox: XULTabBoxElement; tabpanel: XULTabPanelElement; tabpanels: XULTabPanelsElement; tabs: XULTabsElement; template: XULElement; textnode: XULElement; textbox: XULTextBoxElement; titlebar: XULElement; toolbar: XULToolBarElement; toolbarbutton: XULToolBarButtonElement; toolbargrippy: XULToolBarGrippyElement; toolbaritem: XULToolBarItemElement; toolbarpalette: XULToolBarPaletteElement; toolbarseparator: XULToolBarSeparatorElement; toolbarset: XULToolBarSetElement; toolbarspacer: XULToolBarSpacerElement; toolbarspring: XULToolBarSpringElement; toolbox: XULToolBoxElement; tooltip: XULTooltipElement; tree: XULTreeElement; treecell: XULTreeCellElement; treechildren: XULTreeChildrenElement; treecol: XULTreeColElement; treecols: XULTreeColsElement; treeitem: XULTreeItemElement; treerow: XULTreeRowElement; treeseparator: XULTreeSeparatorElement; triple: XULElement; vbox: XULBoxElement; window: XULWindowElement; wizard: XULElement; wizardpage: XULElement; } //#endregion //#region src/helpers/dialog.d.ts /** * Dialog window helper. A superset of XUL dialog. */ declare class DialogHelper extends UITool { /** * Passed to dialog window for data-binding and lifecycle controls. See {@link DialogHelper.setDialogData} */ dialogData: DialogData; /** * Dialog window instance */ window: Window; protected elementProps: ElementProps & { tag: string; }; /** * Create a dialog helper with row \* column grids. * @param row * @param column */ constructor(row: number, column: number); /** * Add a cell at (row, column). Index starts from 0. * @param row * @param column * @param elementProps Cell element props. See {@link ElementProps} * @param cellFlex If the cell is flex. Default true. */ addCell(row: number, column: number, elementProps: TagElementProps, cellFlex?: boolean): this; /** * Add a control button to the bottom of the dialog. * @param label Button label * @param id Button id. * The corresponding id of the last button user clicks before window exit will be set to `dialogData._lastButtonId`. * @param options Options * @param [options.noClose] Don't close window when clicking this button. * @param [options.callback] Callback of button click event. */ addButton(label: string, id?: string, options?: { noClose?: boolean; callback?: (ev: Event) => any; }): this; /** * Dialog data. * @remarks * This object is passed to the dialog window. * * The control button id is in `dialogData._lastButtonId`; * * The data-binding values are in `dialogData`. * ```ts * interface DialogData { * [key: string | number | symbol]: any; * loadLock?: { promise: Promise; resolve: () => void; isResolved: () => boolean }; // resolve after window load (auto-generated) * loadCallback?: Function; // called after window load * unloadLock?: { promise: Promise; resolve: () => void }; // resolve after window unload (auto-generated) * unloadCallback?: Function; // called after window unload * beforeUnloadCallback?: Function; // called before window unload when elements are accessable. * } * ``` * @param dialogData */ setDialogData(dialogData: DialogData): this; /** * Open the dialog * @param title Window title * @param windowFeatures * @param windowFeatures.width Ignored if fitContent is `true`. * @param windowFeatures.height Ignored if fitContent is `true`. * @param windowFeatures.left * @param windowFeatures.top * @param windowFeatures.centerscreen Open window at the center of screen. * @param windowFeatures.resizable If window is resizable. * @param windowFeatures.fitContent Resize the window to content size after elements are loaded. * @param windowFeatures.noDialogMode Dialog mode window only has a close button. Set `true` to make maximize and minimize button visible. * @param windowFeatures.alwaysRaised Is the window always at the top. */ open(title: string, windowFeatures?: { width?: number; height?: number; left?: number; top?: number; centerscreen?: boolean; resizable?: boolean; fitContent?: boolean; noDialogMode?: boolean; alwaysRaised?: boolean; }): this; } interface DialogData { [key: string | number | symbol]: any; loadLock?: { promise: Promise; resolve: () => void; isResolved: () => boolean; }; loadCallback?: () => void; unloadLock?: { promise: Promise; resolve: () => void; }; unloadCallback?: () => void; beforeUnloadCallback?: () => void; l10nFiles?: string | string[]; } //#endregion //#region src/helpers/filePicker.d.ts /** * File picker helper. * @param title window title * @param mode * @param filters Array<[hint string, filter string]> * @param suggestion default file/folder * @param window the parent window. By default it is the main window * @param filterMask built-in filters * @param directory directory in which to open the file picker * @example * ```ts * await new FilePickerHelper( * `${Zotero.getString("fileInterface.import")} MarkDown Document`, * "open", * [["MarkDown File(*.md)", "*.md"]] * ).open(); * ``` */ declare class FilePickerHelper extends BasicTool { private title; private mode; private filters?; private suggestion?; private directory?; private window?; private filterMask?; constructor(title: string, mode: MODE, filters?: [string, string][], suggestion?: string, window?: Window, filterMask?: "all" | "html" | "text" | "images" | "xml" | "apps" | "urls" | "audio" | "video", directory?: string); open(): Promise<(MODE extends "multiple" ? string[] : string) | false>; private getMode; private getFilterMask; } //#endregion //#region src/helpers/guide.d.ts /** * Helper for creating a guide. * Designed for creating a step-by-step guide for users. * @alpha */ declare class GuideHelper extends BasicTool { _steps: GuideStep[]; constructor(); addStep(step: GuideStep): this; addSteps(steps: GuideStep[]): this; show(doc: Document): Promise; highlight(doc: Document, step: GuideStep): Promise; } interface GuideStep { element?: string | Element | (() => Element); title?: string; description?: string; position?: "before_start" | "before_end" | "after_start" | "after_end" | "start_before" | "start_after" | "end_before" | "end_after" | "overlap" | "after_pointer" | "center"; showButtons?: ("next" | "prev" | "close")[]; showProgress?: boolean; disableButtons?: ("next" | "prev" | "close")[]; progressText?: string; closeBtnText?: string; nextBtnText?: string; prevBtnText?: string; onBeforeRender?: GuideHook; onRender?: GuideHook; onExit?: GuideHook; onNextClick?: GuideHook; onPrevClick?: GuideHook; onCloseClick?: GuideHook; onMask?: (props: { mask: (elem: Element) => void; }) => void; } type GuideHook = ({ config, state }: { config: GuideStep; state: GuideState; }) => any; interface GuideState { step: number; steps: GuideStep[]; controller: Guide; } declare class Guide { _window: Window; _id: string; _panel: XULPopupElement; _header: HTMLDivElement; _body: HTMLDivElement; _footer: HTMLDivElement; _progress: HTMLDivElement; _closeButton: XUL.Button; _prevButton: XUL.Button; _nextButton: XUL.Button; _steps?: GuideStep[]; _noClose: boolean; _closed: boolean; _autoNext: boolean; _currentIndex: number; initialized: boolean; _cachedMasks: WeakRef[]; get content(): any; get currentStep(): GuideStep | undefined; get currentTarget(): Element | undefined; get hasNext(): boolean | undefined; get hasPrevious(): boolean | undefined; get hookProps(): Parameters[0]; get panel(): XULPopupElement; constructor(win: Window); show(steps?: GuideStep[]): Promise; hide(): void; abort(): void; moveTo(stepIndex: number): void; moveNext(): void; movePrevious(): void; _handleShown(): void; _handleHidden(): Promise; _centerPanel: () => void; _createMask(targetElement?: Element): void; _removeMask(): void; } //#endregion //#region src/helpers/largePref.d.ts /** * Helper class for storing large amounts of data in Zotero preferences. * * @remarks * The allowed data length for a single preference is at least 100k, * but if this can grow infinitely, like an Array or an Object, * there will be significant performance problems. * * This class stores the keys of data in a single preference as a JSON string of Array, * and stores the values of data in separate preferences. * * You can either use the class as a normal object with `asObject()`, * or use the methods to access the data. */ declare class LargePrefHelper extends BasicTool { private keyPref; private valuePrefPrefix; private innerObj; private hooks; /** * * @param keyPref The preference name for storing the keys of the data. * @param valuePrefPrefix The preference name prefix for storing the values of the data. * @param hooks Hooks for parsing the values of the data. * - `afterGetValue`: A function that takes the value of the data as input and returns the parsed value. * - `beforeSetValue`: A function that takes the key and value of the data as input and returns the parsed key and value. * If `hooks` is `"default"`, no parsing will be done. * If `hooks` is `"parser"`, the values will be parsed as JSON. * If `hooks` is an object, the values will be parsed by the hooks. */ constructor(keyPref: string, valuePrefPrefix: string, hooks?: Partial | "default" | "parser"); /** * Get the object that stores the data. * @returns The object that stores the data. */ asObject(): ProxyObj; /** * Get the Map that stores the data. * @returns The Map that stores the data. */ asMapLike(): Map; /** * Get the keys of the data. * @returns The keys of the data. */ getKeys(): string[]; /** * Set the keys of the data. * @param keys The keys of the data. */ setKeys(keys: string[]): void; /** * Get the value of a key. * @param key The key of the data. * @returns The value of the key. */ getValue(key: string): any; /** * Set the value of a key. * @param key The key of the data. * @param value The value of the key. */ setValue(key: string, value: any): void; /** * Check if a key exists. * @param key The key of the data. * @returns Whether the key exists. */ hasKey(key: string): boolean; /** * Add a key. * @param key The key of the data. */ setKey(key: string): void; /** * Delete a key. * @param key The key of the data. */ deleteKey(key: string): boolean; private constructTempObj; private constructTempMap; } type ProxyObj = Record; declare const defaultHooks: { afterGetValue: ({ value }: { value: string; }) => { value: any; }; beforeSetValue: ({ key, value }: { key: string; value: any; }) => { key: string; value: any; }; }; //#endregion //#region src/helpers/message.d.ts type MessageParams = { [K in keyof T]: T[K] extends ((...params: infer P) => void) ? P : never }; type MessageReturnType = { [K in keyof T]: T[K] extends ((...params: any) => infer R) ? R : never }; interface MessageHandlers { [key: string]: (...data: any[]) => Promise | any; } type PromisedMessageHandlers = { [K in keyof T]: (...data: Parameters) => Promise>> }; interface MessageServerConfig { name: string; handlers: MessageHandlers; target?: Window | Worker; dev?: boolean; canBeDestroyed?: boolean; } interface BuiltInMessageHandlers { _start: () => Promise; _stop: () => Promise; _destroy: () => Promise; _ping: () => Promise; _call: (data: { func: string; args: any[]; }) => Promise; _get: (data: { key: string; }) => Promise; _set: (data: { key: string; value: any; }) => Promise; } /** * Helper class to manage messages between workers/iframes and their parent * @beta * * @example * Use the `MessageHelper` to create a server that can be used to communicate between workers or iframes and their parent. * * In the child `worker.js`: * ```typescript * const handlers = { * async test() { * return "test"; * }, * }; * // Create a new server * const server = new MessageHelper({ * name: "child", * handlers, * canBeDestroyed: true, * }); * // Start the listener * server.start(); * // Export the handlers for type hinting * export { handlers }; * ``` * In the parent: * ```typescript * // Import the handlers * import type { handlers } from "./worker.js"; * // Create a new worker * const worker = new Worker("worker.js"); * // Create a new server with the type from the target handlers * const server = new MessageHelper({ * name: "worker", * handlers: { * async test() { * return "test"; * }, * }, * target: worker, * }); * server.start(); * // Execute the handlers defined in the worker as if they were local * ztoolkit.log(await server.proxy.test()); * // ... * // Stop the server, can be restarted with server.start() * server.stop(); * // Destroy the server and the worker * server.destroy(); * ``` * * @example * Evaluate code in the other side of the server * ```typescript * await server.eval("self.firstName = 'John';"); * ``` * * @example * Get a property from the other side of the server, can be nested. * * Only works if the property is a primitive or a serializable object * ```typescript * ztoolkit.log(await server.get("self.firstName")); * ``` * * @example * Set a property from the other side of the server, can be nested. * * Only works if the property is a primitive or a serializable object * ```typescript * await server.set("self.firstName", "Alice"); * ``` * * @example * Check if the target is alive * ```typescript * ztoolkit.log(await server.isTargetAlive()); * // Alternatively, send a ping message * ztoolkit.log(await server.proxy._ping()); * ``` */ declare class MessageHelper<_TargetHandlers extends MessageHandlers> { protected config: Required; protected env: "webworker" | "chromeworker" | "browser" | "content"; protected listener?: any; running: boolean; /** * Proxy object to call the message handlers */ proxy: PromisedMessageHandlers<_TargetHandlers & BuiltInMessageHandlers>; get target(): Window | Worker; get privileged(): boolean; constructor(config: MessageServerConfig); start(): void; stop(): void; destroy(): void; exec<_HandlersName extends keyof MessageParams<_HandlersType>, _HandlersType extends _TargetHandlers & BuiltInMessageHandlers>(name: _HandlersName, params?: MessageParams<_HandlersType>[_HandlersName], options?: { timeout?: number; }): Promise[_HandlersName]>>; call(func: string, args: any[]): Promise["_call"]>; get(key: string): Promise["_get"]>; set(key: string, value: any): Promise["_set"]>; eval(code: string): Promise["_eval"]>; send(options: { name: string; data: any; jobID?: string; success?: boolean; requestReturn?: boolean; }): Promise; isTargetAlive(): Promise; } //#endregion //#region src/typings/basic.d.ts declare type FunctionNamesOf = keyof FunctionsOf; declare type FunctionsOf = { [K in keyof T as T[K] extends Function ? K : never]: T[K] }; //#endregion //#region src/helpers/patch.d.ts declare class PatchHelper extends BasicTool { private options?; constructor(); setData>(options: PatchOptions): this; enable(): this; disable(): this; } declare interface PatchOptions> { target: T; funcSign: K; patcher: (origin: T[K]) => T[K]; enabled: boolean; } //#endregion //#region src/helpers/progressWindow.d.ts /** * ProgressWindow helper. * @example * Show a popup with success icon * ```ts * const tool = new ZoteroTool(); * tool.createProgressWindow("Addon").createLine({ * type: "success", * text: "Finish" * progress: 100, * }).show(); * ``` * @example * Show a popup and change line content * ```ts * const compat = new ZoteroCompat(); * const tool = new ZoteroTool(); * const popupWin = tool.createProgressWindow("Addon").createLine({ * text: "Loading" * progress: 50, * }).show(-1); * // Do operations * compat.getGlobal("setTimeout")(()=>{ * popupWin.changeLine({ * text: "Finish", * progress: 100, * }); * }, 3000); * ``` */ declare class ProgressWindowHelper { win: Zotero.ProgressWindow; private lines; private closeTime; /** * * @param header window header * @param options * @param options.window * @param options.closeOnClick * @param options.closeTime * @param options.closeOtherProgressWindows */ constructor(header: string, options?: { window?: Window; closeOnClick?: boolean; closeTime?: number; closeOtherProgressWindows?: boolean; }); /** * Create a new line * @param options * @param options.type * @param options.icon * @param options.text * @param options.progress * @param options.idx */ createLine(options: { type?: string; icon?: string; text?: string; progress?: number; idx?: number; }): this; /** * Change the line content * @param options * @param options.type * @param options.icon * @param options.text * @param options.progress * @param options.idx */ changeLine(options: { type?: string; icon?: string; text?: string; progress?: number; idx?: number; }): this; show(closeTime?: number | undefined): this; /** * Set custom icon uri for progress window * @param key * @param uri */ static setIconURI(key: string, uri: string): void; private getIcon; private updateIcons; changeHeadline(text: string, icon?: string, postText?: string): this; addLines(labels: string | { [key: string | number | symbol]: string; }, icons: string | { [key: string | number | symbol]: string; }): this; addDescription(text: string): this; startCloseTimer(ms: number, requireMouseOver?: boolean): this; close(): this; } //#endregion //#region src/helpers/settingsDialog.d.ts /** * Settings dialog helper. Extends DialogHelper with setting management capabilities. */ declare class SettingsDialogHelper extends DialogHelper { private settingsHandlers; private autoSaveButtonIds; private settingBindings; /** * Create a settings dialog helper. * Uses a 2-column grid layout by default (label column + control column) */ constructor(); /** * Set the setting handlers for getting and setting values. * @param getSetting Function to get a setting value by key * @param setSetting Function to set a setting value by key */ setSettingHandlers(getSetting: (key: string) => any, setSetting: (key: string, value: any) => void): this; /** * Add a setting row with label and form control. * @param label Label text for the setting * @param settingKey The key used to store/retrieve the setting * @param controlProps Properties for the form control element * @param options Additional options * @param options.valueType Type of the setting value for proper conversion * @param options.labelProps Properties for the label element * @param options.condition Optional condition function to determine if the setting should be added * (returns true to add, false to skip) * @returns The SettingsDialogHelper instance for chaining */ addSetting(label: string, settingKey: string, controlProps: TagElementProps, options?: { valueType?: "string" | "number" | "boolean"; labelProps?: Partial; condition?: () => boolean; }): this; /** * Add a static row (label + static element) to the settings grid. This is not a form control. * @param label Label text for the row * @param staticElementProps Properties for the static element (e.g., text, icon, etc.) * @param options Additional options * @param options.labelProps Properties for the label element * @param options.condition Optional condition function to determine if the row should be added * @returns The SettingsDialogHelper instance for chaining */ addStaticRow(label: string, staticElementProps: TagElementProps, options?: { labelProps?: Partial; condition?: () => boolean; }): this; /** * Add a control button that will auto-save settings when clicked. * @param label Button label * @param id Button id * @param options Button options * @param options.noClose Don't close window when clicking this button * @param options.validate Validation function for settings data * @param options.callback Callback of button click event */ addAutoSaveButton(label: string, id?: string, options?: { noClose?: boolean; validate?: (data: any) => Promise | true | string; callback?: (ev: Event) => any; }): this; /** * Save all settings using the setting handlers. */ saveAllSettings(): void; /** * Collect and return all current setting values from the dialog controls. */ getAllSettingsData(): Record; /** * Load all settings from the setting handlers. */ loadAllSettings(): void; /** * Override the open method to handle setting loading after window opens. */ open(title: string, windowFeatures?: { width?: number; height?: number; left?: number; top?: number; centerscreen?: boolean; resizable?: boolean; fitContent?: boolean; noDialogMode?: boolean; alwaysRaised?: boolean; }): this; /** * Set control value based on element type and value type. */ private setControlValue; /** * Set control value on an actual DOM element. */ private setControlValueOnElement; /** * Get control value from a DOM element with proper type conversion. */ private getControlValue; } //#endregion //#region src/helpers/virtualizedTable.d.ts /** * VirtualizedTable helper. */ declare class VirtualizedTableHelper extends BasicTool { props: VirtualizedTableProps; localeStrings: { [name: string]: string; }; containerId: string; treeInstance: VirtualizedTable; private window; private React; private ReactDOM; private VirtualizedTable; private IntlProvider; constructor(win: Window); /** * Set properties by name. * @remarks * `id` and `getRowCount` are required. * If `id` is not set, it's a random string. * @param propName Property name * @param propValue Property value */ setProp(propName: K, propValue: V): VirtualizedTableHelper; /** * Set properties object. * @remarks * `id` and `getRowCount` are required. * If `id` is not set, it's a random string. * @param data property object. * @remarks * All available properties: * ```ts * interface VirtualizedTableProps { * id: string; * getRowCount: () => number; * getRowData?: (index: number) => { [dataKey: string]: string }; * // Use `getRowData` instead. This property is generated automatically. * renderItem?: ( * index: number, * selection: TreeSelection, * oldElem: HTMLElement, * columns: ColumnOptions[] * ) => Node; * // Row height specified as lines of text per row. Defaults to 1 * linesPerRow?: number; * // Do not adjust for Zotero-defined font scaling * disableFontSizeScaling?: boolean; * // An array of two elements for alternating row colors * alternatingRowColors?: Array; * // For screen-readers * label?: string; * role?: string; * showHeader?: boolean; * // Array of column objects like the ones in itemTreeColumns.js * columns?: Array; * onColumnPickerMenu?: (event: Event) => void; * onColumnSort?: (columnIndex: number, ascending: 1 | -1) => void; * getColumnPrefs?: () => { [dataKey: string]: any }; * storeColumnPrefs?: (prefs: { [dataKey: string]: any }) => void; * getDefaultColumnOrder?: () => { [dataKey: string]: any }; * // Makes columns unmovable, unsortable, etc * staticColumns?: boolean; * // Used for initial column widths calculation * containerWidth?: number; * // Internal windowed-list ref * treeboxRef?: (innerWindowedList: WindowedList) => any; * // Render with display?: none * hide?: boolean; * multiSelect?: boolean; * onSelectionChange?: ( * selection: TreeSelection, * shouldDebounce: boolean * ) => void; * // The below are for arrow-key navigation * isSelectable?: (index: number) => boolean; * getParentIndex?: (index: number) => number; * isContainer?: (index: number) => boolean; * isContainerEmpty?: (index: number) => boolean; * isContainerOpen?: (index: number) => boolean; * toggleOpenState?: (index: number) => void; * // A function with signature (index?:Number) => result?:String which will be used * // for find-as-you-type navigation. Find-as-you-type is disabled if prop is undefined. * getRowString?: (index: number) => string; * // If you want to perform custom key handling it should be in this function * // if it returns false then virtualized-table's own key handler won't run * onKeyDown?: (e: Event) => boolean; * onKeyUp?: (e: Event) => void; * onDragOver?: (e: Event) => void; * onDrop?: (e: Event) => void; * // Enter, double-clicking * onActivate?: (e: Event, items: number[]) => void; * onFocus?: (e: Event) => void; * onItemContextMenu?: (e: Event, x: number, y: number) => void; * } * ``` */ setProp(data: Partial): VirtualizedTableHelper; /** * Set locale strings, which replaces the table header's label if matches. Default it's `Zotero.Intl.strings` * @param localeStrings */ setLocale(localeStrings: { [name: string]: string; }): this; /** * Set container element id that the table will be rendered on. * @param id element id */ setContainerId(id: string): this; /** * Render the table. * @param selectId Which row to select after rendering * @param onfulfilled callback after successfully rendered * @param onrejected callback after rendering with error */ render(selectId?: number, onfulfilled?: (value: unknown) => unknown, onrejected?: (reason: any) => PromiseLike): this; } interface ColumnOptions { dataKey: string; label: string; iconLabel?: React.ReactElement; defaultSort?: 1 | -1; flex?: number; width?: number; fixedWidth?: boolean; staticWidth?: boolean; minWidth?: number; ignoreInColumnPicker?: boolean; submenu?: boolean; } interface VirtualizedTableProps { id: string; getRowCount: () => number; getRowData?: (index: number) => { [dataKey: string]: string; }; /** * Use `getRowData` instead. This property is generated automatically. * @param index * @param selection * @param oldElem * @param columns */ renderItem?: (index: number, selection: TreeSelection, oldElem: HTMLElement, columns: ColumnOptions[]) => Node; linesPerRow?: number; disableFontSizeScaling?: boolean; alternatingRowColors?: Array; label?: string; role?: string; showHeader?: boolean; columns?: Array; onColumnPickerMenu?: (event: Event) => void; onColumnSort?: (columnIndex: number, ascending: 1 | -1) => void; getColumnPrefs?: () => { [dataKey: string]: any; }; storeColumnPrefs?: (prefs: { [dataKey: string]: any; }) => void; getDefaultColumnOrder?: () => { [dataKey: string]: any; }; staticColumns?: boolean; containerWidth?: number; treeboxRef?: (innerWindowedList: WindowedList) => any; hide?: boolean; multiSelect?: boolean; onSelectionChange?: (selection: TreeSelection, shouldDebounce: boolean) => void; isSelectable?: (index: number) => boolean; getParentIndex?: (index: number) => number; isContainer?: (index: number) => boolean; isContainerEmpty?: (index: number) => boolean; isContainerOpen?: (index: number) => boolean; toggleOpenState?: (index: number) => void; getRowString?: (index: number) => string; onKeyDown?: (e: KeyboardEvent) => boolean; onKeyUp?: (e: KeyboardEvent) => void; onDragOver?: (e: DragEvent) => void; onDrop?: (e: DragEvent) => void; onActivate?: (e: MouseEvent | KeyboardEvent, items: number[]) => void; onFocus?: (e: FocusEvent) => void; onItemContextMenu?: (e: MouseEvent | KeyboardEvent, x: number, y: number) => void; } interface VirtualizedTable extends React.Component { selection: TreeSelection; invalidate: () => void; } /** * Somewhat corresponds to nsITreeSelection * https://udn.realityripple.com/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsITreeSelection * * @property pivot {Number} The selection "pivot". This is the first item the user selected as part of * a ranged select (i.e. shift-select). * @property focused {Number} The currently selected/focused item. * @property count {Number} The number of selected items * @property selected {Set} The set of currently selected items * @property selectEventsSuppressed {Boolean} Controls whether select events are triggered on selection change. */ interface TreeSelection { _tree: VirtualizedTable; pivot: number; focused: number; selected: Set; _selectEventsSuppressed: boolean; /** * @param tree {VirtualizedTable} The tree where selection occurs. Will be used to issue * updates. */ new (tree: VirtualizedTable): this; /** * Returns whether the given index is selected. * @param index {Number} The index is 0-clamped. * @returns {boolean} */ isSelected: (index: number) => boolean; /** * Toggles an item's selection state, updates focused item to index. * @param index {Number} The index is 0-clamped. * @param shouldDebounce {Boolean} Whether the update to the tree should be debounced */ toggleSelect: (index: number, shouldDebounce?: boolean) => void; clearSelection: () => void; /** * Selects an item, updates focused item to index. * @param index {Number} The index is 0-clamped. * @param shouldDebounce {Boolean} Whether the update to the tree should be debounced * @returns {boolean} False if nothing to select and select handlers won't be called */ select: (index: number, shouldDebounce?: boolean) => boolean; rangedSelect: (from: number, to: number, augment: boolean, isSelectAll: boolean) => void; /** * Performs a shift-select from current pivot to provided index. Updates focused item to index. * @param index {Number} The index is 0-clamped. * @param augment {Boolean} Adds to existing selection if true * @param shouldDebounce {Boolean} Whether the update to the tree should be debounced */ shiftSelect: (index: number, augment: boolean, shouldDebounce?: boolean) => void; /** * Calls the onSelectionChange prop on the tree * @param shouldDebounce {Boolean} Whether the update to the tree should be debounced * @private */ _updateTree: (shouldDebounce?: boolean) => void; get count(): number; get selectEventsSuppressed(): boolean; set selectEventsSuppressed(val: boolean); } interface WindowedList { [key: string | number | symbol]: any; } //#endregion //#region src/managers/fieldHook.d.ts /** * Item field hooks manager. */ declare class FieldHookManager extends ManagerTool { private data; private patchHelpers; constructor(base?: BasicTool | BasicOptions); /** * Register `Zotero.Item.getField` hook. * @param type * @param field * @param hook ( field: string, unformatted: boolean, includeBaseMapped: boolean, item: Zotero.Item, original: Function) => string */ register(type: "getField", field: string, hook: typeof getFieldHookFunc): void; /** * Register `Zotero.Item.setField` hook. * @param type * @param field * @param hook ( field: string, value: string, loadIn: boolean, item: Zotero.Item, original: Function) => void */ register(type: "setField", field: string, hook: typeof setFieldHookFunc): void; /** * Register `Zotero.ItemFields.isFieldOfBase` hook. Used in itemBox. * @param type * @param field * @param hook ( field: string, baseField: string, original: Function) => void */ register(type: "isFieldOfBase", field: string, hook: typeof isFieldOfBaseHookFunc): void; unregister(type: "getField" | "setField" | "isFieldOfBase", field: string): void; unregisterAll(): void; } declare function getFieldHookFunc(field: string, unformatted: boolean, includeBaseMapped: boolean, item: Zotero.Item, original: Function): string; declare function setFieldHookFunc(field: string, value: string, loadIn: boolean, item: Zotero.Item, original: Function): boolean; declare function isFieldOfBaseHookFunc(field: string, baseField: string | number, original: Function): boolean; //#endregion //#region src/managers/keyboard.d.ts /** * Register a global keyboard event listener. */ declare class KeyboardManager extends ManagerTool { private _keyboardCallbacks; private _cachedKey?; private id; constructor(base?: BasicTool | BasicOptions); /** * Register a keyboard event listener. * @param callback The callback function. */ register(callback: KeyboardCallback): void; /** * Unregister a keyboard event listener. * @param callback The callback function. */ unregister(callback: KeyboardCallback): void; /** * Unregister all keyboard event listeners. */ unregisterAll(): void; private initKeyboardListener; private unInitKeyboardListener; private initReaderKeyboardListener; private addReaderKeyboardCallback; private _initKeyboardListener; private _unInitKeyboardListener; private triggerKeydown; private triggerKeyup; private dispatchCallback; } type KeyboardEventType = "keydown" | "keyup"; type KeyboardCallback = (event: KeyboardEvent, options: { keyboard?: KeyModifier; type: KeyboardEventType; }) => void; interface KeyModifierStatus { accel: boolean; shift: boolean; control: boolean; meta: boolean; alt: boolean; key: string; } /** * Class to represent key with modifiers */ declare class KeyModifier implements KeyModifierStatus { accel: boolean; shift: boolean; control: boolean; meta: boolean; alt: boolean; key: string; useAccel: boolean; constructor(raw?: string | KeyboardEvent | KeyModifier, options?: { useAccel?: boolean; }); /** * Merge another KeyModifier into this one. * @param newMod the new KeyModifier * @param options * @param options.allowOverwrite * @returns KeyModifier */ merge(newMod: KeyModifier, options?: { allowOverwrite?: boolean; }): this; /** * Check if the current KeyModifier equals to another KeyModifier. * @param newMod the new KeyModifier * @returns true if equals */ equals(newMod: KeyModifier | string): boolean; /** * Get the raw string representation of the KeyModifier. */ getRaw(): string; /** * Get the localized string representation of the KeyModifier. */ getLocalized(): string; /** * Get the un-localized string representation of the KeyModifier. */ private unLocalized; private mergeAttribute; } //#endregion //#region src/managers/toolkitGlobal.d.ts interface GlobalInstance { _ready: boolean; } //#endregion //#region src/managers/prompt.d.ts /** * Prompt for setting up or executing some commands quickly. * * `Shift + P` can show/hide its UI anywhere after registering commands. */ declare class Prompt { private ui; private base; get document(): Document; /** * Record the last text entered */ private lastInputText; /** * Default text */ private defaultText; /** * It controls the max line number of commands displayed in `commandsNode`. */ private maxLineNum; /** * It controls the max number of suggestions. */ private maxSuggestionNum; /** * The top-level HTML div node of `Prompt` */ promptNode: HTMLDivElement; /** * The HTML input node of `Prompt`. */ inputNode: HTMLInputElement; /** * Save all commands registered by all addons. */ commands: Command[]; /** * Initialize `Prompt` but do not create UI. */ constructor(); /** * Initialize `Prompt` UI and then bind events on it. */ initializeUI(): void; private createHTML; /** * Show commands in a new `commandsContainer` * All other `commandsContainer` is hidden * @param commands Command[] * @param clear remove all `commandsContainer` if true */ showCommands(commands: Command[], clear?: boolean): void; /** * Create a `commandsContainer` div element, append to `commandsContainer` and hide others. * @returns commandsNode */ createCommandsContainer(): HTMLDivElement; /** * Return current displayed `commandsContainer` * @returns */ private getCommandsContainer; /** * Create a command item for `Prompt` UI. * @param command * @returns */ createCommandNode(command: Command): HTMLElement; /** * Called when `enter` key is pressed. */ private trigger; /** * Called when `escape` key is pressed. */ private exit; private execCallback; /** * Match suggestions for user's entered text. */ private showSuggestions; /** * Bind events of pressing `keydown` and `keyup` key. */ private initInputEvents; /** * Create a commandsContainer and display a text */ showTip(text: string): HTMLDivElement; /** * Mark the selected item with class `selected`. * @param item HTMLDivElement */ selectItem(item: HTMLDivElement): void; private addStyle; private registerShortcut; } declare class PromptManager extends ManagerTool { prompt: Prompt; /** * Save the commands registered from this manager */ private commands; constructor(base?: BasicTool | BasicOptions); /** * Register commands. Don't forget to call `unregister` on plugin exit. * @param commands Command[] * @example * ```ts * let getReader = () => { * return BasicTool.getZotero().Reader.getByTabID( * (Zotero.getMainWindow().Zotero_Tabs).selectedID * ) * } * * register([ * { * name: "Split Horizontally", * label: "Zotero", * when: () => getReader() as boolean, * callback: (prompt: Prompt) => getReader().menuCmd("splitHorizontally") * }, * { * name: "Split Vertically", * label: "Zotero", * when: () => getReader() as boolean, * callback: (prompt: Prompt) => getReader().menuCmd("splitVertically") * } * ]) * ``` */ register(commands: { name?: string; label?: string; id?: string; when?: () => boolean; callback: ((prompt: Prompt) => Promise) | ((prompt: Prompt) => void) | Command[]; }[]): void; /** * You can delete a command registed before by its name. * @remarks * There is a premise here that the names of all commands registered by a single plugin are not duplicated. * @param id Command.name */ unregister(id: string): void; /** * Call `unregisterAll` on plugin exit. */ unregisterAll(): void; } interface Command { name?: string; label?: string; id?: string; when?: () => boolean; callback: ((prompt: Prompt) => Promise) | ((prompt: Prompt) => void) | Command[]; } interface PromptGlobal extends GlobalInstance { instance: Prompt | undefined; } //#endregion //#region src/tools/extraField.d.ts /** * Get/set extra field APIs. */ declare class ExtraFieldTool extends BasicTool { /** * Get all extra fields * @param item Zotero item * @param parser Parsing mode: * - "enhanced": use the enhanced custom parser (supports duplicate keys) * - "classical": use Zotero’s built-in parser (single value per key) */ getExtraFields(item: Zotero.Item, parser: "classical"): Map; getExtraFields(item: Zotero.Item, parser?: "enhanced"): Map; /** * Get extra field value by key. If it does not exists, return undefined. * @param item * @param key * @param [all] Whether to return all values if the field appears multiple times. */ getExtraField(item: Zotero.Item, key: string, all?: false): string | undefined; getExtraField(item: Zotero.Item, key: string, all: true): string[] | undefined; /** * Replace extra field of an item. * @param item * @param fields * @param [options] Additional options. * @param [options.save] Whether to save the item, default to true. */ replaceExtraFields(item: Zotero.Item, fields: Map, options?: { save?: boolean; }): Promise; /** * Set a key-value pair in the item's extra field. * If the key already exists, it can be overwritten or appended. * @param item Zotero item * @param key Field key * @param value Field value or list of values * @param options Additional options * @param [options.append] Whether to append to existing values, default to false * @param [options.save] Whether to save the item, default to true */ setExtraField(item: Zotero.Item, key: string, value: string | string[], options?: { append?: boolean; save?: boolean; }): Promise; } //#endregion //#region src/tools/reader.d.ts /** * Zotero ReaderInstance APIs. */ declare class ReaderTool extends BasicTool { /** * Get the selected tab reader. * @param waitTime Wait for n MS until the reader is ready */ getReader(waitTime?: number): Promise<_ZoteroTypes.ReaderInstance | undefined>; /** * Get all window readers. */ getWindowReader(): Array<_ZoteroTypes.ReaderWindow>; /** * Get the selected annotation data. * @param reader Target reader * @returns The selected annotation data. */ getSelectedAnnotationData(reader: _ZoteroTypes.ReaderInstance): AnnotationData | undefined; /** * Get the text selection of reader. * @param reader Target reader * @returns The text selection of reader. */ getSelectedText(reader: _ZoteroTypes.ReaderInstance): string; } interface AnnotationData { color?: string; pageLabel: string; position: Record; sortIndex: string; text: string; type: _ZoteroTypes.Annotations.AnnotationType; } declare namespace wait_d_exports { export { waitForReader, waitUntil, waitUntilAsync, waitUtilAsync }; } declare function waitUntil(condition: () => boolean, callback: () => void, interval?: number, timeout?: number): void; declare const waitUtilAsync: typeof waitUntilAsync; declare function waitUntilAsync(condition: () => boolean, interval?: number, timeout?: number): Promise; declare function waitForReader(reader: _ZoteroTypes.ReaderInstance): Promise; //#endregion //#region src/ztoolkit.d.ts /** * ⭐Contains all tools in this lib. Start from here if you are new to this lib. * @remarks * To minimize your plugin, import the modules you need manually. */ declare class ZoteroToolkit extends BasicTool { static _version: string; UI: UITool; Reader: ReaderTool; ExtraField: ExtraFieldTool; FieldHooks: FieldHookManager; Keyboard: KeyboardManager; Prompt: PromptManager; Clipboard: typeof ClipboardHelper; FilePicker: typeof FilePickerHelper; Patch: typeof PatchHelper; ProgressWindow: typeof ProgressWindowHelper; VirtualizedTable: typeof VirtualizedTableHelper; Dialog: typeof DialogHelper; LargePrefObject: typeof LargePrefHelper; Guide: typeof GuideHelper; constructor(); /** * Unregister everything created by managers. */ unregisterAll(): void; } //#endregion export { BasicOptions, BasicTool, ClipboardHelper, ColumnOptions, Command, DialogData, DialogHelper, ElementProps, ExtraFieldTool, FieldHookManager, FilePickerHelper, FragmentElementProps, GuideHelper, HTMLElementProps, KeyModifier, KeyboardManager, LargePrefHelper, ManagerTool, MessageHelper, PatchHelper, ProgressWindowHelper, Prompt, PromptGlobal, PromptManager, ReaderTool, SettingsDialogHelper, TagElementProps, UIOptions, UITool, VirtualizedTableHelper, XULElementProps, ZoteroToolkit, _importESModule, getFieldHookFunc, isFieldOfBaseHookFunc, makeHelperTool, setFieldHookFunc, unregister, wait_d_exports as wait };