refactor: make examples more friendly
This commit is contained in:
parent
6426ae5198
commit
4469cbc82d
101
README.md
101
README.md
@ -19,6 +19,32 @@ This is an addon/plugin template for [Zotero](https://www.zotero.org/).
|
|||||||
- Some sample code of UI and lifecycle.
|
- Some sample code of UI and lifecycle.
|
||||||
- ⭐Compatibilities for Zotero 6 & Zotero 7.(using [zotero-plugin-toolkit](https://github.com/windingwind/zotero-plugin-toolkit))
|
- ⭐Compatibilities for Zotero 6 & Zotero 7.(using [zotero-plugin-toolkit](https://github.com/windingwind/zotero-plugin-toolkit))
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
This repo provides examples for [zotero-plugin-toolkit](https://github.com/windingwind/zotero-plugin-toolkit) APIs.
|
||||||
|
|
||||||
|
Search `@example` in `src/examples.ts`. The examples are called in `src/hooks.ts`.
|
||||||
|
|
||||||
|
### Basic Examples
|
||||||
|
|
||||||
|
- registerNotifier
|
||||||
|
- registerPrefs, unregisterPrefs
|
||||||
|
|
||||||
|
### UI Examples
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- registerStyleSheet(the official make-it-red example)
|
||||||
|
- registerRightClickMenuItem
|
||||||
|
- registerRightClickMenuPopup
|
||||||
|
- registerWindowMenuWithSeprator
|
||||||
|
- registerExtraColumn
|
||||||
|
- registerExtraColumnWithCustomCell
|
||||||
|
- registerCustomCellRenderer
|
||||||
|
- registerLibraryTabPanel
|
||||||
|
- registerReaderTabPanel
|
||||||
|
- unregisterUIExamples
|
||||||
|
|
||||||
## Quick Start Guide
|
## Quick Start Guide
|
||||||
|
|
||||||
- Fork this repo;
|
- Fork this repo;
|
||||||
@ -46,58 +72,38 @@ This is an addon/plugin template for [Zotero](https://www.zotero.org/).
|
|||||||
- Run `npm run build` to build the plugin in production mode. Run `npm run build-dev` to build the plugin in development mode. The xpi for installation and the built code is under builds folder.
|
- Run `npm run build` to build the plugin in production mode. Run `npm run build-dev` to build the plugin in development mode. The xpi for installation and the built code is under builds folder.
|
||||||
|
|
||||||
> What the difference between dev & prod?
|
> What the difference between dev & prod?
|
||||||
|
>
|
||||||
> - This environment variable is stored in `Zotero.AddonTemplate.env`. The outputs to console is disabled in prod mode.
|
> - This environment variable is stored in `Zotero.AddonTemplate.env`. The outputs to console is disabled in prod mode.
|
||||||
> - You can decide what users cannot see/use based on this variable.
|
> - You can decide what users cannot see/use based on this variable.
|
||||||
|
|
||||||
### About Life Cycle
|
### About Hooks
|
||||||
|
|
||||||
|
> See also `src/hooks.ts`
|
||||||
|
|
||||||
1. When install/enable/startup triggered from Zotero, `bootstrap.js` > `startup` is called
|
1. When install/enable/startup triggered from Zotero, `bootstrap.js` > `startup` is called
|
||||||
- Wait for Zotero ready
|
- Wait for Zotero ready
|
||||||
- Prepare global variables `ctx`. They are available globally in the plugin scope
|
- Prepare global variables `ctx`. They are available globally in the plugin scope
|
||||||
- Load `index.js` (the main entrance of plugin code, built from `index.ts`)
|
- Load `index.js` (the main entrance of plugin code, built from `index.ts`)
|
||||||
- Register resources if Zotero 7+
|
- Register resources if Zotero 7+
|
||||||
2. In the main entrance `index.js`, the plugin object is injected under `Zotero` and `events.ts` > `onInit` is called.
|
2. In the main entrance `index.js`, the plugin object is injected under `Zotero` and `hooks.ts` > `onStartup` is called.
|
||||||
- Initialize anything you want, including notify listeners, preference panes(`initPrefs`), and UI elements(`initViews`).
|
- Initialize anything you want, including notify listeners, preference panes, and UI elements.
|
||||||
3. When uninstall/disabled triggered from Zotero, `bootstrap.js` > `shutdown` is called.
|
3. When uninstall/disabled triggered from Zotero, `bootstrap.js` > `shutdown` is called.
|
||||||
- `events.ts` > `onUninit` is called. Remove UI elements(`unInitViews`), preference panes(`uninitPrefs`), or anything created by the plugin.
|
- `events.ts` > `onShutdown` is called. Remove UI elements, preference panes, or anything created by the plugin.
|
||||||
- Remove scripts and release resources.
|
- Remove scripts and release resources.
|
||||||
|
|
||||||
### About Global Variables
|
### About Global Variables
|
||||||
|
|
||||||
|
> See also `src/index.ts`
|
||||||
|
|
||||||
The bootstrapped plugin runs in a sandbox, which does not have default global variables like `Zotero` or `window`, which we used to have in the overlay plugins' window environment.
|
The bootstrapped plugin runs in a sandbox, which does not have default global variables like `Zotero` or `window`, which we used to have in the overlay plugins' window environment.
|
||||||
|
|
||||||
This template registers the following variables to the global scope:
|
This template registers the following variables to the global scope:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
Zotero, ZoteroPane, Zotero_Tabs, window, document, rootURI, ZToolkit
|
Zotero, ZoteroPane, Zotero_Tabs, window, document, rootURI, ztoolkit, addon;
|
||||||
```
|
```
|
||||||
|
|
||||||
See `src/events.ts` > `initGlobalVariables` for more details.
|
### About Preference
|
||||||
|
|
||||||
|
|
||||||
### Examples
|
|
||||||
|
|
||||||
See https://github.com/windingwind/zotero-plugin-toolkit for more detailed API documentations.
|
|
||||||
|
|
||||||
#### Menu (file, edit, view, ...) & Right-click Menu (item, collection/library)
|
|
||||||
|
|
||||||
**File Menu**
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
https://github.com/windingwind/zotero-addon-template/blob/574ce88b9fd3535a9d062db51cf16e99dda35288/src/views.ts#L52-L60
|
|
||||||
|
|
||||||
**Item Menu**
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
https://github.com/windingwind/zotero-addon-template/blob/574ce88b9fd3535a9d062db51cf16e99dda35288/src/views.ts#L23-L51
|
|
||||||
|
|
||||||
`insertMenuItem` resolved the input object and inject the menu items.
|
|
||||||
|
|
||||||
You can choose an anchor element and insert before/after it using `insertPosition` and `anchorElement`. Default the insert position is the end of the menu.
|
|
||||||
|
|
||||||
#### Preference, for both Zotero 6 and Zotero 7 (all in bootstrap)
|
|
||||||
|
|
||||||
Zotero 6 doesn't support preference pane injection in bootstrap mode, thus I write a register for Zotero 6 or lower.
|
Zotero 6 doesn't support preference pane injection in bootstrap mode, thus I write a register for Zotero 6 or lower.
|
||||||
|
|
||||||
@ -133,7 +139,7 @@ Remember to call `unregisterPrefPane()` on plugin unload.
|
|||||||
|
|
||||||
https://github.com/windingwind/zotero-addon-template/blob/574ce88b9fd3535a9d062db51cf16e99dda35288/src/views.ts#L88-L90
|
https://github.com/windingwind/zotero-addon-template/blob/574ce88b9fd3535a9d062db51cf16e99dda35288/src/views.ts#L88-L90
|
||||||
|
|
||||||
#### Create Elements API
|
### Create Elements API
|
||||||
|
|
||||||
The plugin template provides new APIs for bootstrap plugins. We have two reasons to use these APIs, instead of the `createElement/createElementNS`:
|
The plugin template provides new APIs for bootstrap plugins. We have two reasons to use these APIs, instead of the `createElement/createElementNS`:
|
||||||
|
|
||||||
@ -142,30 +148,13 @@ The plugin template provides new APIs for bootstrap plugins. We have two reasons
|
|||||||
|
|
||||||
There are more advanced APIs for creating elements in batch: `creatElementsFromJSON`. Input an element tree in JSON and return a fragment/element. These elements are also maintained by this plugin template.
|
There are more advanced APIs for creating elements in batch: `creatElementsFromJSON`. Input an element tree in JSON and return a fragment/element. These elements are also maintained by this plugin template.
|
||||||
|
|
||||||
#### Extra Column in Library
|
|
||||||
|
|
||||||
Using [Zotero Plugin Toolkit:ItemTreeTool](https://github.com/windingwind/zotero-plugin-toolkit/blob/HEAD/docs/zotero-plugin-toolkit.itemtreetool.md) to register an extra column in `src/views.ts`.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
ZToolkit.ItemTree.registerExample();
|
|
||||||
```
|
|
||||||
This will register a column with dataKey `test`. Looks like:
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Remember to unregister it when exiting.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
ZToolkit.ItemTree.unregister("test");
|
|
||||||
```
|
|
||||||
|
|
||||||
### Directory Structure
|
### Directory Structure
|
||||||
|
|
||||||
This section shows the directory structure of a template.
|
This section shows the directory structure of a template.
|
||||||
|
|
||||||
- All `.js/.ts` code files are in `./src`;
|
- All `.js/.ts` code files are in `./src`;
|
||||||
- Addon config files: `./addon/chrome.manifest`, `./addon/install.rdf`;
|
- Addon config files: `./addon/chrome.manifest`, `./addon/install.rdf`, and `./addon/manifest.json`;
|
||||||
- UI files: `./addon/chrome/content/*.xul`. The `overlay.xul` also defines the main entrance;
|
- UI files: `./addon/chrome/content/*.xhtml`.
|
||||||
- Locale files: `./addon/chrome/locale/[*.dtd, *.properties]`;
|
- Locale files: `./addon/chrome/locale/[*.dtd, *.properties]`;
|
||||||
- Resource files: `./addon/chrome/skin/default/__addonRef__/*.dtd`;
|
- Resource files: `./addon/chrome/skin/default/__addonRef__/*.dtd`;
|
||||||
- Preferences file: `./addon/chrome/defaults/preferences/defaults.js`;
|
- Preferences file: `./addon/chrome/defaults/preferences/defaults.js`;
|
||||||
@ -184,8 +173,9 @@ This section shows the directory structure of a template.
|
|||||||
├─.github # github conf
|
├─.github # github conf
|
||||||
│
|
│
|
||||||
├─addon # addon dir
|
├─addon # addon dir
|
||||||
│ │ chrome.manifest #addon conf
|
│ │ chrome.manifest # for Zotero 6
|
||||||
│ │ install.rdf # addon install conf
|
│ │ manifest.json # for Zotero 7
|
||||||
|
│ │ install.rdf # addon install conf, for Zotero 6
|
||||||
│ │ bootstrap.js # addon load/unload script, like a main.c
|
│ │ bootstrap.js # addon load/unload script, like a main.c
|
||||||
│ │
|
│ │
|
||||||
│ └─chrome
|
│ └─chrome
|
||||||
@ -211,10 +201,9 @@ This section shows the directory structure of a template.
|
|||||||
│
|
│
|
||||||
└─src # source code
|
└─src # source code
|
||||||
│ index.ts # main entry
|
│ index.ts # main entry
|
||||||
│ module.ts # module class
|
|
||||||
│ addon.ts # base class
|
│ addon.ts # base class
|
||||||
│ events.ts # events class
|
│ hooks.ts # lifecycle hooks
|
||||||
│ views.ts # UI class
|
│ examples.ts # examples factory
|
||||||
│ locale.ts # Locale class for properties files
|
│ locale.ts # Locale class for properties files
|
||||||
└─ prefs.ts # preferences class
|
└─ prefs.ts # preferences class
|
||||||
|
|
||||||
|
2
addon/bootstrap.js
vendored
2
addon/bootstrap.js
vendored
@ -102,7 +102,7 @@ function shutdown({ id, version, resourceURI, rootURI }, reason) {
|
|||||||
Components.interfaces.nsISupports
|
Components.interfaces.nsISupports
|
||||||
).wrappedJSObject;
|
).wrappedJSObject;
|
||||||
}
|
}
|
||||||
Zotero.AddonTemplate.events.onUnInit(Zotero);
|
Zotero.AddonTemplate.hooks.onShutdown();
|
||||||
|
|
||||||
Cc["@mozilla.org/intl/stringbundle;1"]
|
Cc["@mozilla.org/intl/stringbundle;1"]
|
||||||
.getService(Components.interfaces.nsIStringBundleService)
|
.getService(Components.interfaces.nsIStringBundleService)
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
startup.begin=Addon is loading
|
||||||
|
startup.finish=Addon is ready
|
||||||
menuitem.label=Addon Template: Menuitem
|
menuitem.label=Addon Template: Menuitem
|
||||||
menupopup.label=Addon Template: Menupopup
|
menupopup.label=Addon Template: Menupopup
|
||||||
menuitem.submenulabel=Addon Template
|
menuitem.submenulabel=Addon Template
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
menuitem.label=Addon Template: 菜单
|
startup.begin=插件加载中
|
||||||
menupopup.label=Addon Template: 弹出菜单
|
startup.finish=插件已就绪
|
||||||
menuitem.submenulabel=Addon Template
|
menuitem.label=插件模板: 菜单
|
||||||
menuitem.filemenulabel=Addon Template: 文件菜单
|
menupopup.label=插件模板: 弹出菜单
|
||||||
|
menuitem.submenulabel=插件模板:子菜单
|
||||||
|
menuitem.filemenulabel=插件模板: 文件菜单
|
||||||
prefs.title=插件模板
|
prefs.title=插件模板
|
||||||
tabpanel.lib.tab.label=库标签
|
tabpanel.lib.tab.label=库标签
|
||||||
tabpanel.reader.tab.label=阅读器标签
|
tabpanel.reader.tab.label=阅读器标签
|
2
build.js
2
build.js
@ -101,7 +101,7 @@ async function main() {
|
|||||||
.build({
|
.build({
|
||||||
entryPoints: ["src/index.ts"],
|
entryPoints: ["src/index.ts"],
|
||||||
define: {
|
define: {
|
||||||
__env__: process.env.NODE_ENV,
|
__env__: `"${process.env.NODE_ENV}"`,
|
||||||
},
|
},
|
||||||
bundle: true,
|
bundle: true,
|
||||||
// Entry should be the same as addon/chrome/content/overlay.xul
|
// Entry should be the same as addon/chrome/content/overlay.xul
|
||||||
|
@ -40,6 +40,6 @@
|
|||||||
"esbuild": "^0.16.10",
|
"esbuild": "^0.16.10",
|
||||||
"release-it": "^14.14.3",
|
"release-it": "^14.14.3",
|
||||||
"replace-in-file": "^6.3.5",
|
"replace-in-file": "^6.3.5",
|
||||||
"zotero-types": "^0.1.2"
|
"zotero-types": "^0.1.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
17
src/addon.ts
17
src/addon.ts
@ -1,25 +1,24 @@
|
|||||||
import AddonEvents from "./events";
|
import AddonHooks from "./hooks";
|
||||||
import AddonPrefs from "./prefs";
|
import AddonPrefs from "./prefs";
|
||||||
import AddonViews from "./views";
|
|
||||||
import AddonLocale from "./locale";
|
import AddonLocale from "./locale";
|
||||||
|
|
||||||
class Addon {
|
class Addon {
|
||||||
// Env type, see build.js
|
// Env type, see build.js
|
||||||
public env!: "development" | "production";
|
public env!: "development" | "production";
|
||||||
|
// If addon is disabled/removed, set it false
|
||||||
|
public alive: boolean;
|
||||||
// Lifecycle events
|
// Lifecycle events
|
||||||
public events: AddonEvents;
|
public hooks: AddonHooks;
|
||||||
// UI operations
|
|
||||||
public views: AddonViews;
|
|
||||||
// Scripts for prefpane window
|
// Scripts for prefpane window
|
||||||
public prefs: AddonPrefs;
|
public prefs: AddonPrefs;
|
||||||
// Runtime locale with .properties
|
// Runtime locale with .properties
|
||||||
public locale: AddonLocale;
|
public locale: AddonLocale;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.events = new AddonEvents(this);
|
this.alive = true;
|
||||||
this.views = new AddonViews(this);
|
this.hooks = new AddonHooks();
|
||||||
this.prefs = new AddonPrefs(this);
|
this.prefs = new AddonPrefs();
|
||||||
this.locale = new AddonLocale(this);
|
this.locale = new AddonLocale();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
119
src/events.ts
119
src/events.ts
@ -1,119 +0,0 @@
|
|||||||
import Addon from "./addon";
|
|
||||||
import AddonModule from "./module";
|
|
||||||
import { config } from "../package.json";
|
|
||||||
import ZoteroToolkit from "zotero-plugin-toolkit";
|
|
||||||
|
|
||||||
class AddonEvents extends AddonModule {
|
|
||||||
constructor(parent: Addon) {
|
|
||||||
super(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function is the setup code of the addon
|
|
||||||
public async onInit() {
|
|
||||||
this.initGlobalVariables();
|
|
||||||
// @ts-ignore
|
|
||||||
const development = "development";
|
|
||||||
const production = "production";
|
|
||||||
// The env will be replaced after esbuild
|
|
||||||
// @ts-ignore
|
|
||||||
this._Addon.env = __env__;
|
|
||||||
ZToolkit.Tool.logOptionsGlobal.disableConsole =
|
|
||||||
this._Addon.env === "production";
|
|
||||||
ZToolkit.Tool.log("init called");
|
|
||||||
|
|
||||||
// Initialize locale provider
|
|
||||||
this._Addon.locale.initLocale();
|
|
||||||
// Initialize preference window
|
|
||||||
this.initPrefs();
|
|
||||||
// Initialize notifier callback
|
|
||||||
this.initNotifier();
|
|
||||||
// Initialize UI elements
|
|
||||||
this._Addon.views.initViews();
|
|
||||||
}
|
|
||||||
|
|
||||||
public onUnInit(): void {
|
|
||||||
ZToolkit.Tool.log("uninit called");
|
|
||||||
this.unInitPrefs();
|
|
||||||
// Remove elements and do clean up
|
|
||||||
this._Addon.views.unInitViews();
|
|
||||||
// Remove addon object
|
|
||||||
Zotero.AddonTemplate = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
private initGlobalVariables() {
|
|
||||||
_globalThis.ZToolkit = new ZoteroToolkit();
|
|
||||||
ZToolkit.Tool.logOptionsGlobal.prefix = `[${config.addonName}]`;
|
|
||||||
_globalThis.Zotero = ZToolkit.Compat.getGlobal("Zotero");
|
|
||||||
_globalThis.ZoteroPane = ZToolkit.Compat.getGlobal("ZoteroPane");
|
|
||||||
_globalThis.Zotero_Tabs = ZToolkit.Compat.getGlobal("Zotero_Tabs");
|
|
||||||
_globalThis.window = ZToolkit.Compat.getGlobal("window");
|
|
||||||
_globalThis.document = ZToolkit.Compat.getGlobal("document");
|
|
||||||
ZToolkit.Tool.log("initializeing global variables");
|
|
||||||
}
|
|
||||||
|
|
||||||
private initNotifier() {
|
|
||||||
const callback = {
|
|
||||||
notify: async (
|
|
||||||
event: string,
|
|
||||||
type: string,
|
|
||||||
ids: Array<string>,
|
|
||||||
extraData: { [key: string]: any }
|
|
||||||
) => {
|
|
||||||
// You can add your code to the corresponding notify type
|
|
||||||
if (
|
|
||||||
event == "select" &&
|
|
||||||
type == "tab" &&
|
|
||||||
extraData[ids[0]].type == "reader"
|
|
||||||
) {
|
|
||||||
// Select a reader tab
|
|
||||||
}
|
|
||||||
if (event == "add" && type == "item") {
|
|
||||||
// Add an item
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Register the callback in Zotero as an item observer
|
|
||||||
let notifierID = Zotero.Notifier.registerObserver(callback, [
|
|
||||||
"tab",
|
|
||||||
"item",
|
|
||||||
"file",
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Unregister callback when the window closes (important to avoid a memory leak)
|
|
||||||
Zotero.getMainWindow().addEventListener(
|
|
||||||
"unload",
|
|
||||||
function (e: Event) {
|
|
||||||
Zotero.Notifier.unregisterObserver(notifierID);
|
|
||||||
},
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private initPrefs() {
|
|
||||||
const prefOptions = {
|
|
||||||
pluginID: config.addonID,
|
|
||||||
src: rootURI + "chrome/content/preferences.xhtml",
|
|
||||||
label: this._Addon.locale.getString("prefs.title"),
|
|
||||||
image: `chrome://${config.addonRef}/content/icons/favicon.png`,
|
|
||||||
extraDTD: [`chrome://${config.addonRef}/locale/overlay.dtd`],
|
|
||||||
defaultXUL: true,
|
|
||||||
onload: (win: Window) => {
|
|
||||||
this._Addon.prefs.initPreferences(win);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
if (ZToolkit.Compat.isZotero7()) {
|
|
||||||
Zotero.PreferencePanes.register(prefOptions);
|
|
||||||
} else {
|
|
||||||
ZToolkit.Compat.registerPrefPane(prefOptions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private unInitPrefs() {
|
|
||||||
if (!ZToolkit.Compat.isZotero7()) {
|
|
||||||
ZToolkit.Compat.unregisterPrefPane();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default AddonEvents;
|
|
@ -1,27 +1,100 @@
|
|||||||
import Addon from "./addon";
|
import { log } from "zotero-plugin-toolkit/dist/utils";
|
||||||
import AddonModule from "./module";
|
|
||||||
import { config } from "../package.json";
|
import { config } from "../package.json";
|
||||||
|
|
||||||
class AddonViews extends AddonModule {
|
export function example(type?: string): MethodDecorator {
|
||||||
// You can store some element in the object attributes
|
return function (
|
||||||
private progressWindowIcon: { [key: string]: string };
|
target: Object,
|
||||||
|
propertyKey: string | symbol,
|
||||||
constructor(parent: Addon) {
|
descriptor: PropertyDescriptor
|
||||||
super(parent);
|
) {
|
||||||
this.progressWindowIcon = {
|
log("Calling example", target, type, propertyKey, descriptor);
|
||||||
success: "chrome://zotero/skin/tick.png",
|
return descriptor;
|
||||||
fail: "chrome://zotero/skin/cross.png",
|
|
||||||
default: `chrome://${config.addonRef}/content/icons/favicon.png`,
|
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BasicExampleFactory {
|
||||||
|
@example()
|
||||||
|
static registerNotifier() {
|
||||||
|
const callback = {
|
||||||
|
notify: async (
|
||||||
|
event: string,
|
||||||
|
type: string,
|
||||||
|
ids: Array<string>,
|
||||||
|
extraData: { [key: string]: any }
|
||||||
|
) => {
|
||||||
|
if (!addon.alive) {
|
||||||
|
this.unregisterNotifier(notifierID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ztoolkit.Tool.log("notify", event, type, ids, extraData);
|
||||||
|
// You can add your code to the corresponding notify type
|
||||||
|
if (
|
||||||
|
event == "select" &&
|
||||||
|
type == "tab" &&
|
||||||
|
extraData[ids[0]].type == "reader"
|
||||||
|
) {
|
||||||
|
// Select a reader tab
|
||||||
|
}
|
||||||
|
if (event == "add" && type == "item") {
|
||||||
|
// Add an item
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Register the callback in Zotero as an item observer
|
||||||
|
const notifierID = Zotero.Notifier.registerObserver(callback, [
|
||||||
|
"tab",
|
||||||
|
"item",
|
||||||
|
"file",
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Unregister callback when the window closes (important to avoid a memory leak)
|
||||||
|
window.addEventListener(
|
||||||
|
"unload",
|
||||||
|
(e: Event) => {
|
||||||
|
this.unregisterNotifier(notifierID);
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public initViews() {
|
@example()
|
||||||
// You can init the UI elements that
|
private static unregisterNotifier(notifierID: string) {
|
||||||
// cannot be initialized with overlay.xul
|
Zotero.Notifier.unregisterObserver(notifierID);
|
||||||
ZToolkit.Tool.log("Initializing UI");
|
}
|
||||||
|
|
||||||
// register style sheet
|
@example()
|
||||||
const styles = ZToolkit.UI.creatElementsFromJSON(document, {
|
static registerPrefs() {
|
||||||
|
const prefOptions = {
|
||||||
|
pluginID: config.addonID,
|
||||||
|
src: rootURI + "chrome/content/preferences.xhtml",
|
||||||
|
label: addon.locale.getString("prefs.title"),
|
||||||
|
image: `chrome://${config.addonRef}/content/icons/favicon.png`,
|
||||||
|
extraDTD: [`chrome://${config.addonRef}/locale/overlay.dtd`],
|
||||||
|
defaultXUL: true,
|
||||||
|
onload: (win: Window) => {
|
||||||
|
addon.prefs.initPreferences(win);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if (ztoolkit.Compat.isZotero7()) {
|
||||||
|
Zotero.PreferencePanes.register(prefOptions);
|
||||||
|
} else {
|
||||||
|
ztoolkit.Compat.registerPrefPane(prefOptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@example()
|
||||||
|
static unregisterPrefs() {
|
||||||
|
if (!ztoolkit.Compat.isZotero7()) {
|
||||||
|
ztoolkit.Compat.unregisterPrefPane();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class UIExampleFactory {
|
||||||
|
@example()
|
||||||
|
static registerStyleSheet() {
|
||||||
|
const styles = ztoolkit.UI.creatElementsFromJSON(document, {
|
||||||
tag: "link",
|
tag: "link",
|
||||||
directAttributes: {
|
directAttributes: {
|
||||||
type: "text/css",
|
type: "text/css",
|
||||||
@ -33,26 +106,32 @@ class AddonViews extends AddonModule {
|
|||||||
document
|
document
|
||||||
.getElementById("zotero-item-pane-content")
|
.getElementById("zotero-item-pane-content")
|
||||||
?.classList.add("makeItRed");
|
?.classList.add("makeItRed");
|
||||||
|
}
|
||||||
|
|
||||||
|
@example()
|
||||||
|
static registerRightClickMenuItem() {
|
||||||
const menuIcon = `chrome://${config.addonRef}/content/icons/favicon@0.5x.png`;
|
const menuIcon = `chrome://${config.addonRef}/content/icons/favicon@0.5x.png`;
|
||||||
// item menuitem with icon
|
// item menuitem with icon
|
||||||
ZToolkit.UI.insertMenuItem("item", {
|
ztoolkit.UI.insertMenuItem("item", {
|
||||||
tag: "menuitem",
|
tag: "menuitem",
|
||||||
id: "zotero-itemmenu-addontemplate-test",
|
id: "zotero-itemmenu-addontemplate-test",
|
||||||
label: this._Addon.locale.getString("menuitem.label"),
|
label: addon.locale.getString("menuitem.label"),
|
||||||
oncommand: "alert('Hello World! Default Menuitem.')",
|
oncommand: "alert('Hello World! Default Menuitem.')",
|
||||||
icon: menuIcon,
|
icon: menuIcon,
|
||||||
});
|
});
|
||||||
// item menupopup with sub-menuitems
|
}
|
||||||
ZToolkit.UI.insertMenuItem(
|
|
||||||
|
@example()
|
||||||
|
static registerRightClickMenuPopup() {
|
||||||
|
ztoolkit.UI.insertMenuItem(
|
||||||
"item",
|
"item",
|
||||||
{
|
{
|
||||||
tag: "menu",
|
tag: "menu",
|
||||||
label: this._Addon.locale.getString("menupopup.label"),
|
label: addon.locale.getString("menupopup.label"),
|
||||||
subElementOptions: [
|
subElementOptions: [
|
||||||
{
|
{
|
||||||
tag: "menuitem",
|
tag: "menuitem",
|
||||||
label: this._Addon.locale.getString("menuitem.submenulabel"),
|
label: addon.locale.getString("menuitem.submenulabel"),
|
||||||
oncommand: "alert('Hello World! Sub Menuitem.')",
|
oncommand: "alert('Hello World! Sub Menuitem.')",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -62,24 +141,24 @@ class AddonViews extends AddonModule {
|
|||||||
"#zotero-itemmenu-addontemplate-test"
|
"#zotero-itemmenu-addontemplate-test"
|
||||||
) as XUL.MenuItem
|
) as XUL.MenuItem
|
||||||
);
|
);
|
||||||
ZToolkit.UI.insertMenuItem("menuFile", {
|
}
|
||||||
|
|
||||||
|
@example()
|
||||||
|
static registerWindowMenuWithSeprator() {
|
||||||
|
ztoolkit.UI.insertMenuItem("menuFile", {
|
||||||
tag: "menuseparator",
|
tag: "menuseparator",
|
||||||
});
|
});
|
||||||
// menu->File menuitem
|
// menu->File menuitem
|
||||||
ZToolkit.UI.insertMenuItem("menuFile", {
|
ztoolkit.UI.insertMenuItem("menuFile", {
|
||||||
tag: "menuitem",
|
tag: "menuitem",
|
||||||
label: this._Addon.locale.getString("menuitem.filemenulabel"),
|
label: addon.locale.getString("menuitem.filemenulabel"),
|
||||||
oncommand: "alert('Hello World! File Menuitem.')",
|
oncommand: "alert('Hello World! File Menuitem.')",
|
||||||
});
|
});
|
||||||
/**
|
}
|
||||||
* Example: menu items ends
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
@example()
|
||||||
* Example: extra column starts
|
static async registerExtraColumn() {
|
||||||
*/
|
await ztoolkit.ItemTree.register(
|
||||||
// Initialize extra columns
|
|
||||||
ZToolkit.ItemTree.register(
|
|
||||||
"test1",
|
"test1",
|
||||||
"text column",
|
"text column",
|
||||||
(
|
(
|
||||||
@ -94,7 +173,11 @@ class AddonViews extends AddonModule {
|
|||||||
iconPath: "chrome://zotero/skin/cross.png",
|
iconPath: "chrome://zotero/skin/cross.png",
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
ZToolkit.ItemTree.register(
|
}
|
||||||
|
|
||||||
|
@example()
|
||||||
|
static async registerExtraColumnWithCustomCell() {
|
||||||
|
await ztoolkit.ItemTree.register(
|
||||||
"test2",
|
"test2",
|
||||||
"custom column",
|
"custom column",
|
||||||
(
|
(
|
||||||
@ -117,15 +200,11 @@ class AddonViews extends AddonModule {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
/**
|
}
|
||||||
* Example: extra column ends
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
@example()
|
||||||
* Example: custom cell starts
|
static async registerCustomCellRenderer() {
|
||||||
*/
|
await ztoolkit.ItemTree.addRenderCellHook(
|
||||||
// Customize cells
|
|
||||||
ZToolkit.ItemTree.addRenderCellHook(
|
|
||||||
"title",
|
"title",
|
||||||
(index: number, data: string, column: any, original: Function) => {
|
(index: number, data: string, column: any, original: Function) => {
|
||||||
const span = original(index, data, column) as HTMLSpanElement;
|
const span = original(index, data, column) as HTMLSpanElement;
|
||||||
@ -134,17 +213,17 @@ class AddonViews extends AddonModule {
|
|||||||
return span;
|
return span;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
/**
|
// @ts-ignore
|
||||||
* Example: custom cell ends
|
// This is a private method. Make it public in toolkit.
|
||||||
*/
|
await ztoolkit.ItemTree.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
@example()
|
||||||
* Example: extra library tab starts
|
static registerLibraryTabPanel() {
|
||||||
*/
|
const tabId = ztoolkit.UI.registerLibraryTabPanel(
|
||||||
const libTabId = ZToolkit.UI.registerLibraryTabPanel(
|
addon.locale.getString("tabpanel.lib.tab.label"),
|
||||||
this._Addon.locale.getString("tabpanel.lib.tab.label"),
|
|
||||||
(panel: XUL.Element, win: Window) => {
|
(panel: XUL.Element, win: Window) => {
|
||||||
const elem = ZToolkit.UI.creatElementsFromJSON(win.document, {
|
const elem = ztoolkit.UI.creatElementsFromJSON(win.document, {
|
||||||
tag: "vbox",
|
tag: "vbox",
|
||||||
namespace: "xul",
|
namespace: "xul",
|
||||||
subElementOptions: [
|
subElementOptions: [
|
||||||
@ -172,7 +251,7 @@ class AddonViews extends AddonModule {
|
|||||||
{
|
{
|
||||||
type: "click",
|
type: "click",
|
||||||
listener: () => {
|
listener: () => {
|
||||||
ZToolkit.UI.unregisterLibraryTabPanel(libTabId);
|
ztoolkit.UI.unregisterLibraryTabPanel(tabId);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -185,30 +264,26 @@ class AddonViews extends AddonModule {
|
|||||||
targetIndex: 1,
|
targetIndex: 1,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
/**
|
}
|
||||||
* Example: extra library tab ends
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
@example()
|
||||||
* Example: extra reader tab starts
|
static async registerReaderTabPanel() {
|
||||||
*/
|
const tabId = await ztoolkit.UI.registerReaderTabPanel(
|
||||||
const readerTabId = `${config.addonRef}-extra-reader-tab`;
|
addon.locale.getString("tabpanel.reader.tab.label"),
|
||||||
ZToolkit.UI.registerReaderTabPanel(
|
|
||||||
this._Addon.locale.getString("tabpanel.reader.tab.label"),
|
|
||||||
(
|
(
|
||||||
panel: XUL.Element,
|
panel: XUL.TabPanel | undefined,
|
||||||
deck: XUL.Deck,
|
deck: XUL.Deck,
|
||||||
win: Window,
|
win: Window,
|
||||||
reader: _ZoteroReaderInstance
|
reader: _ZoteroReaderInstance
|
||||||
) => {
|
) => {
|
||||||
if (!panel) {
|
if (!panel) {
|
||||||
ZToolkit.Tool.log(
|
ztoolkit.Tool.log(
|
||||||
"This reader do not have right-side bar. Adding reader tab skipped."
|
"This reader do not have right-side bar. Adding reader tab skipped."
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ZToolkit.Tool.log(reader);
|
ztoolkit.Tool.log(reader);
|
||||||
const elem = ZToolkit.UI.creatElementsFromJSON(win.document, {
|
const elem = ztoolkit.UI.creatElementsFromJSON(win.document, {
|
||||||
tag: "vbox",
|
tag: "vbox",
|
||||||
id: `${config.addonRef}-${reader._instanceID}-extra-reader-tab-div`,
|
id: `${config.addonRef}-${reader._instanceID}-extra-reader-tab-div`,
|
||||||
namespace: "xul",
|
namespace: "xul",
|
||||||
@ -254,7 +329,7 @@ class AddonViews extends AddonModule {
|
|||||||
{
|
{
|
||||||
type: "click",
|
type: "click",
|
||||||
listener: () => {
|
listener: () => {
|
||||||
ZToolkit.UI.unregisterReaderTabPanel(readerTabId);
|
ztoolkit.UI.unregisterReaderTabPanel(tabId);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -264,49 +339,13 @@ class AddonViews extends AddonModule {
|
|||||||
panel.append(elem);
|
panel.append(elem);
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
tabId: readerTabId,
|
|
||||||
targetIndex: 1,
|
targetIndex: 1,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
/**
|
|
||||||
* Example: extra reader tab ends
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public unInitViews() {
|
@example()
|
||||||
ZToolkit.Tool.log("Uninitializing UI");
|
static unregisterUIExamples() {
|
||||||
ZToolkit.unregisterAll();
|
ztoolkit.unregisterAll();
|
||||||
// toolkit.UI.removeAddonElements();
|
|
||||||
// // Remove extra columns
|
|
||||||
// toolkit.ItemTree.unregister("test1");
|
|
||||||
// toolkit.ItemTree.unregister("test2");
|
|
||||||
|
|
||||||
// // Remove title cell patch
|
|
||||||
// toolkit.ItemTree.removeRenderCellHook("title");
|
|
||||||
|
|
||||||
// toolkit.UI.unregisterReaderTabPanel(
|
|
||||||
// `${config.addonRef}-extra-reader-tab`
|
|
||||||
// );
|
|
||||||
}
|
|
||||||
|
|
||||||
public showProgressWindow(
|
|
||||||
header: string,
|
|
||||||
context: string,
|
|
||||||
type: string = "default",
|
|
||||||
t: number = 5000
|
|
||||||
) {
|
|
||||||
// A simple wrapper of the Zotero ProgressWindow
|
|
||||||
let progressWindow = new Zotero.ProgressWindow({ closeOnClick: true });
|
|
||||||
progressWindow.changeHeadline(header);
|
|
||||||
progressWindow.progress = new progressWindow.ItemProgress(
|
|
||||||
this.progressWindowIcon[type],
|
|
||||||
context
|
|
||||||
);
|
|
||||||
progressWindow.show();
|
|
||||||
if (t > 0) {
|
|
||||||
progressWindow.startCloseTimer(t);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AddonViews;
|
|
62
src/hooks.ts
Normal file
62
src/hooks.ts
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import { BasicExampleFactory, UIExampleFactory } from "./examples";
|
||||||
|
import { changeProgressWindowLine, showProgressWindow } from "./tools/progress";
|
||||||
|
import { config } from "../package.json";
|
||||||
|
|
||||||
|
class AddonHooks {
|
||||||
|
public async onStartup() {
|
||||||
|
addon.locale.initLocale();
|
||||||
|
|
||||||
|
const w = showProgressWindow(
|
||||||
|
config.addonName,
|
||||||
|
addon.locale.getString("startup.begin"),
|
||||||
|
"default",
|
||||||
|
-1
|
||||||
|
);
|
||||||
|
changeProgressWindowLine(w, { newProgress: 0 });
|
||||||
|
|
||||||
|
BasicExampleFactory.registerPrefs();
|
||||||
|
|
||||||
|
BasicExampleFactory.registerNotifier();
|
||||||
|
|
||||||
|
await Zotero.Promise.delay(1000);
|
||||||
|
changeProgressWindowLine(w, {
|
||||||
|
newProgress: 30,
|
||||||
|
newText: `[30%] ${addon.locale.getString("startup.begin")}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
UIExampleFactory.registerStyleSheet();
|
||||||
|
|
||||||
|
UIExampleFactory.registerRightClickMenuItem();
|
||||||
|
|
||||||
|
UIExampleFactory.registerRightClickMenuPopup();
|
||||||
|
|
||||||
|
UIExampleFactory.registerWindowMenuWithSeprator();
|
||||||
|
|
||||||
|
await UIExampleFactory.registerExtraColumn();
|
||||||
|
|
||||||
|
await UIExampleFactory.registerExtraColumnWithCustomCell();
|
||||||
|
|
||||||
|
await UIExampleFactory.registerCustomCellRenderer();
|
||||||
|
|
||||||
|
UIExampleFactory.registerLibraryTabPanel();
|
||||||
|
|
||||||
|
await UIExampleFactory.registerReaderTabPanel();
|
||||||
|
|
||||||
|
await Zotero.Promise.delay(1000);
|
||||||
|
changeProgressWindowLine(w, {
|
||||||
|
newProgress: 100,
|
||||||
|
newText: `[100%] ${addon.locale.getString("startup.finish")}`,
|
||||||
|
});
|
||||||
|
w.startCloseTimer(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
public onShutdown(): void {
|
||||||
|
BasicExampleFactory.unregisterPrefs();
|
||||||
|
UIExampleFactory.unregisterUIExamples();
|
||||||
|
// Remove addon object
|
||||||
|
addon.alive = false;
|
||||||
|
delete Zotero.AddonTemplate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AddonHooks;
|
23
src/index.ts
23
src/index.ts
@ -1,7 +1,22 @@
|
|||||||
|
import ZoteroToolkit from "zotero-plugin-toolkit";
|
||||||
|
import { getGlobal } from "zotero-plugin-toolkit/dist/utils";
|
||||||
import Addon from "./addon";
|
import Addon from "./addon";
|
||||||
|
import { config } from "../package.json";
|
||||||
|
|
||||||
if (!Zotero.AddonTemplate) {
|
if (!getGlobal("Zotero").AddonTemplate) {
|
||||||
Zotero.AddonTemplate = new Addon();
|
// Set global variables
|
||||||
// @ts-ignore
|
_globalThis.Zotero = getGlobal("Zotero");
|
||||||
Zotero.AddonTemplate.events.onInit();
|
_globalThis.ZoteroPane = getGlobal("ZoteroPane");
|
||||||
|
_globalThis.Zotero_Tabs = getGlobal("Zotero_Tabs");
|
||||||
|
_globalThis.window = getGlobal("window");
|
||||||
|
_globalThis.document = getGlobal("document");
|
||||||
|
_globalThis.ztoolkit = new ZoteroToolkit();
|
||||||
|
_globalThis.addon = new Addon();
|
||||||
|
// The env will be replaced after esbuild
|
||||||
|
addon.env = __env__;
|
||||||
|
ztoolkit.Tool.logOptionsGlobal.prefix = `[${config.addonName}]`;
|
||||||
|
ztoolkit.Tool.logOptionsGlobal.disableConsole = addon.env === "production";
|
||||||
|
Zotero.AddonTemplate = addon;
|
||||||
|
// Trigger addon hook for initialization
|
||||||
|
addon.hooks.onStartup();
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import AddonModule from "./module";
|
|
||||||
import { config } from "../package.json";
|
import { config } from "../package.json";
|
||||||
|
|
||||||
class AddonLocale extends AddonModule {
|
class AddonLocale {
|
||||||
private stringBundle: any;
|
private stringBundle: any;
|
||||||
|
|
||||||
public initLocale() {
|
public initLocale() {
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
import Addon from "./addon";
|
|
||||||
|
|
||||||
class AddonModule {
|
|
||||||
protected _Addon: Addon;
|
|
||||||
constructor(parent: Addon) {
|
|
||||||
this._Addon = parent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default AddonModule;
|
|
14
src/prefs.ts
14
src/prefs.ts
@ -1,17 +1,12 @@
|
|||||||
import Addon from "./addon";
|
|
||||||
import AddonModule from "./module";
|
|
||||||
import { config } from "../package.json";
|
import { config } from "../package.json";
|
||||||
|
|
||||||
class AddonPrefs extends AddonModule {
|
class AddonPrefs {
|
||||||
private _window!: Window;
|
private _window!: Window;
|
||||||
constructor(parent: Addon) {
|
|
||||||
super(parent);
|
|
||||||
}
|
|
||||||
public initPreferences(_window: Window) {
|
public initPreferences(_window: Window) {
|
||||||
// This function is called when the prefs window is opened
|
// This function is called when the prefs window is opened
|
||||||
// See addon/chrome/content/preferences.xul onpaneload
|
// See addon/chrome/content/preferences.xul onpaneload
|
||||||
this._window = _window;
|
this._window = _window;
|
||||||
ZToolkit.Tool.log("init preferences");
|
|
||||||
this.updatePrefsUI();
|
this.updatePrefsUI();
|
||||||
this.bindPrefEvents();
|
this.bindPrefEvents();
|
||||||
}
|
}
|
||||||
@ -20,14 +15,13 @@ class AddonPrefs extends AddonModule {
|
|||||||
// You can initialize some UI elements on prefs window
|
// You can initialize some UI elements on prefs window
|
||||||
// with this._window.document
|
// with this._window.document
|
||||||
// Or bind some events to the elements
|
// Or bind some events to the elements
|
||||||
ZToolkit.Tool.log("init preferences UI");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bindPrefEvents() {
|
private bindPrefEvents() {
|
||||||
this._window.document
|
this._window.document
|
||||||
.querySelector(`#zotero-prefpane-${config.addonRef}-enable`)
|
.querySelector(`#zotero-prefpane-${config.addonRef}-enable`)
|
||||||
?.addEventListener("command", (e) => {
|
?.addEventListener("command", (e) => {
|
||||||
ZToolkit.Tool.log(e);
|
ztoolkit.Tool.log(e);
|
||||||
this._window.alert(
|
this._window.alert(
|
||||||
`Successfully changed to ${(e.target as XUL.Checkbox).checked}!`
|
`Successfully changed to ${(e.target as XUL.Checkbox).checked}!`
|
||||||
);
|
);
|
||||||
@ -36,7 +30,7 @@ class AddonPrefs extends AddonModule {
|
|||||||
this._window.document
|
this._window.document
|
||||||
.querySelector(`#zotero-prefpane-${config.addonRef}-input`)
|
.querySelector(`#zotero-prefpane-${config.addonRef}-input`)
|
||||||
?.addEventListener("change", (e) => {
|
?.addEventListener("change", (e) => {
|
||||||
ZToolkit.Tool.log(e);
|
ztoolkit.Tool.log(e);
|
||||||
this._window.alert(
|
this._window.alert(
|
||||||
`Successfully changed to ${(e.target as HTMLInputElement).value}!`
|
`Successfully changed to ${(e.target as HTMLInputElement).value}!`
|
||||||
);
|
);
|
||||||
|
48
src/tools/progress.ts
Normal file
48
src/tools/progress.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { config } from "../../package.json";
|
||||||
|
|
||||||
|
const progressWindowIcon = {
|
||||||
|
success: "chrome://zotero/skin/tick.png",
|
||||||
|
fail: "chrome://zotero/skin/cross.png",
|
||||||
|
default: `chrome://${config.addonRef}/content/icons/favicon.png`,
|
||||||
|
};
|
||||||
|
|
||||||
|
export function showProgressWindow(
|
||||||
|
header: string,
|
||||||
|
context: string,
|
||||||
|
type: "success" | "fail" | "default" = "default",
|
||||||
|
t: number = 5000
|
||||||
|
): _ZoteroProgressWindow {
|
||||||
|
// A simple wrapper of the Zotero ProgressWindow
|
||||||
|
let progressWindow = new Zotero.ProgressWindow({
|
||||||
|
closeOnClick: true,
|
||||||
|
}) as _ZoteroProgressWindow;
|
||||||
|
progressWindow.changeHeadline(header);
|
||||||
|
// @ts-ignore
|
||||||
|
progressWindow.progress = new progressWindow.ItemProgress(
|
||||||
|
progressWindowIcon[type],
|
||||||
|
context
|
||||||
|
);
|
||||||
|
progressWindow.show();
|
||||||
|
if (t > 0) {
|
||||||
|
progressWindow.startCloseTimer(t);
|
||||||
|
}
|
||||||
|
return progressWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function changeProgressWindowLine(
|
||||||
|
progressWindow: _ZoteroProgressWindow,
|
||||||
|
options: {
|
||||||
|
newText?: string;
|
||||||
|
newIcon?: string;
|
||||||
|
newProgress?: number;
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
// @ts-ignore
|
||||||
|
const progress = progressWindow.progress as _ZoteroItemProgress;
|
||||||
|
if (!progress) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
options.newText && progress.setText(options.newText);
|
||||||
|
options.newIcon && progress.setIcon(options.newIcon);
|
||||||
|
options.newProgress && progress.setProgress(options.newProgress);
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"experimentalDecorators": true,
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"target": "ES2016",
|
"target": "ES2016",
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
|
9
typing/global.d.ts
vendored
9
typing/global.d.ts
vendored
@ -5,9 +5,14 @@ declare const _globalThis: {
|
|||||||
Zotero_Tabs: typeof Zotero_Tabs;
|
Zotero_Tabs: typeof Zotero_Tabs;
|
||||||
window: Window;
|
window: Window;
|
||||||
document: Document;
|
document: Document;
|
||||||
ZToolkit: typeof ZToolkit;
|
ztoolkit: typeof ztoolkit;
|
||||||
|
addon: typeof addon;
|
||||||
};
|
};
|
||||||
|
|
||||||
declare const ZToolkit: import("zotero-plugin-toolkit").ZoteroToolkit;
|
declare const ztoolkit: import("zotero-plugin-toolkit").ZoteroToolkit;
|
||||||
|
|
||||||
declare const rootURI: string;
|
declare const rootURI: string;
|
||||||
|
|
||||||
|
declare const addon: import("../src/addon").default;
|
||||||
|
|
||||||
|
declare const __env__: "production" | "development";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user