add: window load hook
This commit is contained in:
parent
96245a0923
commit
4f5f6f8e12
53
addon/bootstrap.js
vendored
53
addon/bootstrap.js
vendored
@ -11,6 +11,8 @@ if (typeof Zotero == "undefined") {
|
||||
|
||||
var chromeHandle;
|
||||
|
||||
var windowListener;
|
||||
|
||||
// In Zotero 6, bootstrap methods are called before Zotero is initialized, and using include.js
|
||||
// to get the Zotero XPCOM service would risk breaking Zotero startup. Instead, wait for the main
|
||||
// Zotero window to open and get the Zotero object from there.
|
||||
@ -18,53 +20,72 @@ var chromeHandle;
|
||||
// In Zotero 7, bootstrap methods are not called until Zotero is initialized, and the 'Zotero' is
|
||||
// automatically made available.
|
||||
async function waitForZotero() {
|
||||
await new Promise(async (resolve) => {
|
||||
if (typeof Zotero != "undefined") {
|
||||
await Zotero.initializationPromise;
|
||||
resolve();
|
||||
}
|
||||
|
||||
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
var windows = Services.wm.getEnumerator("navigator:browser");
|
||||
var found = false;
|
||||
const { Services } = ChromeUtils.import(
|
||||
"resource://gre/modules/Services.jsm",
|
||||
);
|
||||
const windows = Services.wm.getEnumerator("navigator:browser");
|
||||
let found = false;
|
||||
while (windows.hasMoreElements()) {
|
||||
let win = windows.getNext();
|
||||
if (win.Zotero) {
|
||||
Zotero = win.Zotero;
|
||||
found = true;
|
||||
resolve();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
await new Promise((resolve) => {
|
||||
var listener = {
|
||||
windowListener = {
|
||||
onOpenWindow: function (aWindow) {
|
||||
// Wait for the window to finish loading
|
||||
let domWindow = aWindow
|
||||
const domWindow = aWindow
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
|
||||
domWindow.addEventListener(
|
||||
"load",
|
||||
function () {
|
||||
async function () {
|
||||
domWindow.removeEventListener("load", arguments.callee, false);
|
||||
if (domWindow.Zotero) {
|
||||
Services.wm.removeListener(listener);
|
||||
if (!found && domWindow.Zotero) {
|
||||
Zotero = domWindow.Zotero;
|
||||
resolve();
|
||||
} else if (
|
||||
domWindow.location.href ===
|
||||
"chrome://zotero/content/zoteroPane.xhtml"
|
||||
) {
|
||||
// Call the hook for the main window load event
|
||||
// Note that this is not called the first time the window is opened
|
||||
// (when Zotero is initialized), but only when the window is re-opened
|
||||
// after being closed
|
||||
await Zotero.__addonInstance__?.hooks.onMainWindowLoad(domWindow);
|
||||
}
|
||||
},
|
||||
false,
|
||||
);
|
||||
},
|
||||
};
|
||||
Services.wm.addListener(listener);
|
||||
});
|
||||
onCloseWindow: function (aWindow) {
|
||||
const domWindow = aWindow
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
|
||||
if (
|
||||
domWindow.location.href === "chrome://zotero/content/zoteroPane.xhtml"
|
||||
) {
|
||||
Zotero.__addonInstance__?.hooks.onMainWindowUnload(domWindow);
|
||||
}
|
||||
await Zotero.initializationPromise;
|
||||
},
|
||||
};
|
||||
Services.wm.addListener(windowListener);
|
||||
});
|
||||
}
|
||||
|
||||
function install(data, reason) {}
|
||||
|
||||
async function startup({ id, version, resourceURI, rootURI }, reason) {
|
||||
await waitForZotero();
|
||||
await Zotero.initializationPromise;
|
||||
|
||||
// String 'rootURI' introduced in Zotero 7
|
||||
if (!rootURI) {
|
||||
@ -100,6 +121,8 @@ function shutdown({ id, version, resourceURI, rootURI }, reason) {
|
||||
if (reason === APP_SHUTDOWN) {
|
||||
return;
|
||||
}
|
||||
Services.wm.removeListener(windowListener);
|
||||
|
||||
if (typeof Zotero === "undefined") {
|
||||
Zotero = Components.classes["@zotero.org/Zotero;1"].getService(
|
||||
Components.interfaces.nsISupports,
|
||||
|
44
src/addon.ts
44
src/addon.ts
@ -1,14 +1,14 @@
|
||||
import ZoteroToolkit from "zotero-plugin-toolkit/dist/index";
|
||||
import { ColumnOptions } from "zotero-plugin-toolkit/dist/helpers/virtualizedTable";
|
||||
import { DialogHelper } from "zotero-plugin-toolkit/dist/helpers/dialog";
|
||||
import hooks from "./hooks";
|
||||
import { createZToolkit } from "./utils/ztoolkit";
|
||||
|
||||
class Addon {
|
||||
public data: {
|
||||
alive: boolean;
|
||||
// Env type, see build.js
|
||||
env: "development" | "production";
|
||||
// ztoolkit: MyToolkit;
|
||||
ztoolkit: ZoteroToolkit;
|
||||
ztoolkit: ZToolkit;
|
||||
locale?: {
|
||||
current: any;
|
||||
};
|
||||
@ -28,47 +28,11 @@ class Addon {
|
||||
this.data = {
|
||||
alive: true,
|
||||
env: __env__,
|
||||
// ztoolkit: new MyToolkit(),
|
||||
ztoolkit: new ZoteroToolkit(),
|
||||
ztoolkit: createZToolkit(),
|
||||
};
|
||||
this.hooks = hooks;
|
||||
this.api = {};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alternatively, import toolkit modules you use to minify the plugin size.
|
||||
*
|
||||
* Steps to replace the default `ztoolkit: ZoteroToolkit` with your `ztoolkit: MyToolkit`:
|
||||
*
|
||||
* 1. Uncomment this file's line 30: `ztoolkit: new MyToolkit(),`
|
||||
* and comment line 31: `ztoolkit: new ZoteroToolkit(),`.
|
||||
* 2. Uncomment this file's line 10: `ztoolkit: MyToolkit;` in this file
|
||||
* and comment line 11: `ztoolkit: ZoteroToolkit;`.
|
||||
* 3. Uncomment `../typings/global.d.ts` line 12: `declare const ztoolkit: import("../src/addon").MyToolkit;`
|
||||
* and comment line 13: `declare const ztoolkit: import("zotero-plugin-toolkit").ZoteroToolkit;`.
|
||||
*
|
||||
* You can now add the modules under the `MyToolkit` class.
|
||||
*/
|
||||
|
||||
import { BasicTool, unregister } from "zotero-plugin-toolkit/dist/basic";
|
||||
import { UITool } from "zotero-plugin-toolkit/dist/tools/ui";
|
||||
import { PreferencePaneManager } from "zotero-plugin-toolkit/dist/managers/preferencePane";
|
||||
import { DialogHelper } from "zotero-plugin-toolkit/dist/helpers/dialog";
|
||||
|
||||
export class MyToolkit extends BasicTool {
|
||||
UI: UITool;
|
||||
PreferencePane: PreferencePaneManager;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.UI = new UITool(this);
|
||||
this.PreferencePane = new PreferencePaneManager(this);
|
||||
}
|
||||
|
||||
unregisterAll() {
|
||||
unregister(this);
|
||||
}
|
||||
}
|
||||
|
||||
export default Addon;
|
||||
|
29
src/hooks.ts
29
src/hooks.ts
@ -8,6 +8,7 @@ import {
|
||||
import { config } from "../package.json";
|
||||
import { getString, initLocale } from "./utils/locale";
|
||||
import { registerPrefsScripts } from "./modules/preferenceScript";
|
||||
import { createZToolkit } from "./utils/ztoolkit";
|
||||
|
||||
async function onStartup() {
|
||||
await Promise.all([
|
||||
@ -16,10 +17,19 @@ async function onStartup() {
|
||||
Zotero.uiReadyPromise,
|
||||
]);
|
||||
initLocale();
|
||||
ztoolkit.ProgressWindow.setIconURI(
|
||||
"default",
|
||||
`chrome://${config.addonRef}/content/icons/favicon.png`,
|
||||
);
|
||||
|
||||
BasicExampleFactory.registerPrefs();
|
||||
|
||||
BasicExampleFactory.registerNotifier();
|
||||
|
||||
await onMainWindowLoad(window);
|
||||
}
|
||||
|
||||
async function onMainWindowLoad(win: Window): Promise<void> {
|
||||
// Create ztoolkit for every window
|
||||
const _ztoolkit = createZToolkit();
|
||||
addon.data.ztoolkit = _ztoolkit;
|
||||
_globalThis.ztoolkit = _ztoolkit;
|
||||
|
||||
const popupWin = new ztoolkit.ProgressWindow(config.addonName, {
|
||||
closeOnClick: true,
|
||||
@ -32,10 +42,6 @@ async function onStartup() {
|
||||
})
|
||||
.show();
|
||||
|
||||
BasicExampleFactory.registerPrefs();
|
||||
|
||||
BasicExampleFactory.registerNotifier();
|
||||
|
||||
KeyExampleFactory.registerShortcuts();
|
||||
|
||||
await Zotero.Promise.delay(1000);
|
||||
@ -81,6 +87,11 @@ async function onStartup() {
|
||||
addon.hooks.onDialogEvents("dialogExample");
|
||||
}
|
||||
|
||||
async function onMainWindowUnload(win: Window): Promise<void> {
|
||||
ztoolkit.unregisterAll();
|
||||
addon.data.dialog?.window?.close();
|
||||
}
|
||||
|
||||
function onShutdown(): void {
|
||||
ztoolkit.unregisterAll();
|
||||
addon.data.dialog?.window?.close();
|
||||
@ -173,6 +184,8 @@ function onDialogEvents(type: string) {
|
||||
export default {
|
||||
onStartup,
|
||||
onShutdown,
|
||||
onMainWindowLoad,
|
||||
onMainWindowUnload,
|
||||
onNotify,
|
||||
onPrefsEvent,
|
||||
onShortcuts,
|
||||
|
24
src/index.ts
24
src/index.ts
@ -7,21 +7,21 @@ const basicTool = new BasicTool();
|
||||
if (!basicTool.getGlobal("Zotero")[config.addonInstance]) {
|
||||
// Set global variables
|
||||
_globalThis.Zotero = basicTool.getGlobal("Zotero");
|
||||
_globalThis.ZoteroPane = basicTool.getGlobal("ZoteroPane");
|
||||
_globalThis.Zotero_Tabs = basicTool.getGlobal("Zotero_Tabs");
|
||||
_globalThis.window = basicTool.getGlobal("window");
|
||||
_globalThis.document = basicTool.getGlobal("document");
|
||||
defineGlobal("window");
|
||||
defineGlobal("document");
|
||||
defineGlobal("ZoteroPane");
|
||||
defineGlobal("Zotero_Tabs");
|
||||
_globalThis.addon = new Addon();
|
||||
_globalThis.ztoolkit = addon.data.ztoolkit;
|
||||
ztoolkit.basicOptions.log.prefix = `[${config.addonName}]`;
|
||||
ztoolkit.basicOptions.log.disableConsole = addon.data.env === "production";
|
||||
ztoolkit.UI.basicOptions.ui.enableElementJSONLog =
|
||||
addon.data.env === "development";
|
||||
ztoolkit.UI.basicOptions.ui.enableElementDOMLog =
|
||||
addon.data.env === "development";
|
||||
ztoolkit.basicOptions.debug.disableDebugBridgePassword =
|
||||
addon.data.env === "development";
|
||||
Zotero[config.addonInstance] = addon;
|
||||
// Trigger addon hook for initialization
|
||||
addon.hooks.onStartup();
|
||||
}
|
||||
|
||||
function defineGlobal(name: Parameters<BasicTool["getGlobal"]>[0]) {
|
||||
Object.defineProperty(_globalThis, name, {
|
||||
get() {
|
||||
return basicTool.getGlobal(name);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
48
src/utils/ztoolkit.ts
Normal file
48
src/utils/ztoolkit.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import ZoteroToolkit from "zotero-plugin-toolkit";
|
||||
import { config } from "../../package.json";
|
||||
|
||||
export { createZToolkit };
|
||||
|
||||
function createZToolkit() {
|
||||
const _ztoolkit = new ZoteroToolkit();
|
||||
/**
|
||||
* Alternatively, import toolkit modules you use to minify the plugin size.
|
||||
* You can add the modules under the `MyToolkit` class below and uncomment the following line.
|
||||
*/
|
||||
// const _ztoolkit = new MyToolkit();
|
||||
initZToolkit(_ztoolkit);
|
||||
return _ztoolkit;
|
||||
}
|
||||
|
||||
function initZToolkit(_ztoolkit: ReturnType<typeof createZToolkit>) {
|
||||
const env = __env__;
|
||||
_ztoolkit.basicOptions.log.prefix = `[${config.addonName}]`;
|
||||
_ztoolkit.basicOptions.log.disableConsole = env === "production";
|
||||
_ztoolkit.UI.basicOptions.ui.enableElementJSONLog = __env__ === "development";
|
||||
_ztoolkit.UI.basicOptions.ui.enableElementDOMLog = __env__ === "development";
|
||||
_ztoolkit.basicOptions.debug.disableDebugBridgePassword =
|
||||
__env__ === "development";
|
||||
_ztoolkit.ProgressWindow.setIconURI(
|
||||
"default",
|
||||
`chrome://${config.addonRef}/content/icons/favicon.png`,
|
||||
);
|
||||
}
|
||||
|
||||
import { BasicTool, unregister } from "zotero-plugin-toolkit/dist/basic";
|
||||
import { UITool } from "zotero-plugin-toolkit/dist/tools/ui";
|
||||
import { PreferencePaneManager } from "zotero-plugin-toolkit/dist/managers/preferencePane";
|
||||
|
||||
class MyToolkit extends BasicTool {
|
||||
UI: UITool;
|
||||
PreferencePane: PreferencePaneManager;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.UI = new UITool(this);
|
||||
this.PreferencePane = new PreferencePaneManager(this);
|
||||
}
|
||||
|
||||
unregisterAll() {
|
||||
unregister(this);
|
||||
}
|
||||
}
|
9
typings/global.d.ts
vendored
9
typings/global.d.ts
vendored
@ -5,12 +5,15 @@ declare const _globalThis: {
|
||||
Zotero_Tabs: typeof Zotero_Tabs;
|
||||
window: Window;
|
||||
document: Document;
|
||||
ztoolkit: typeof ztoolkit;
|
||||
ztoolkit: ZToolkit;
|
||||
addon: typeof addon;
|
||||
};
|
||||
|
||||
// declare const ztoolkit: import("../src/addon").MyToolkit;
|
||||
declare const ztoolkit: import("zotero-plugin-toolkit").ZoteroToolkit;
|
||||
declare type ZToolkit = ReturnType<
|
||||
typeof import("../src/utils/ztoolkit").createZToolkit
|
||||
>;
|
||||
|
||||
declare const ztoolkit: ZToolkit;
|
||||
|
||||
declare const rootURI: string;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user