97 lines
2.6 KiB
TypeScript
97 lines
2.6 KiB
TypeScript
export async function waitNoMoreThan<T>(
|
|
promise: Promise<T>,
|
|
timeout: number = 3000,
|
|
message: string = "Timeout",
|
|
) {
|
|
let resolved = false;
|
|
|
|
return Promise.any([
|
|
promise.then((result) => {
|
|
resolved = true;
|
|
return result;
|
|
}),
|
|
Zotero.Promise.delay(timeout).then(() => {
|
|
if (resolved) return;
|
|
throw new Error(message);
|
|
}),
|
|
]);
|
|
}
|
|
|
|
export async function waitForNotifierEvent(
|
|
event: _ZoteroTypes.Notifier.Event,
|
|
type: _ZoteroTypes.Notifier.Type,
|
|
timeout: number = 3000,
|
|
) {
|
|
if (!event) throw new Error("event not provided");
|
|
let resolved = false;
|
|
|
|
return waitNoMoreThan(
|
|
new Promise((resolve, reject) => {
|
|
const notifierID = Zotero.Notifier.registerObserver(
|
|
{
|
|
notify: function (ev, type, ids, extraData) {
|
|
if (ev == event) {
|
|
Zotero.Notifier.unregisterObserver(notifierID);
|
|
resolved = true;
|
|
|
|
resolve({
|
|
ids: ids,
|
|
extraData: extraData,
|
|
});
|
|
}
|
|
},
|
|
},
|
|
[type],
|
|
"test",
|
|
101,
|
|
);
|
|
}),
|
|
timeout,
|
|
);
|
|
}
|
|
|
|
export function waitForTabSelectEvent(timeout: number = 3000) {
|
|
return waitForNotifierEvent("select", "tab", timeout);
|
|
}
|
|
|
|
/**
|
|
* Waits for a window with a specific URL to open. Returns a promise for the window, and
|
|
* optionally passes the window to a callback immediately for use with modal dialogs,
|
|
* which prevent async code from continuing
|
|
*/
|
|
export async function waitForWindow(uri: string, timeout: number = 3000) {
|
|
return waitNoMoreThan(
|
|
new Promise<Window>((resolve, reject) => {
|
|
const loadObserver = function (ev: Event) {
|
|
ev.originalTarget?.removeEventListener("load", loadObserver, false);
|
|
const href = (ev.target as Window)?.location.href;
|
|
Zotero.debug("Window opened: " + href);
|
|
|
|
if (href != uri) {
|
|
Zotero.debug(`Ignoring window ${href} in waitForWindow()`);
|
|
return;
|
|
}
|
|
|
|
Services.ww.unregisterNotification(winObserver);
|
|
const win = ev.target?.ownerGlobal;
|
|
// Give window code time to run on load
|
|
win?.setTimeout(function () {
|
|
resolve(win);
|
|
});
|
|
};
|
|
const winObserver = {
|
|
observe: function (subject: Window, topic: string, data: any) {
|
|
if (topic != "domwindowopened") return;
|
|
subject.addEventListener("load", loadObserver, false);
|
|
},
|
|
} as nsIObserver;
|
|
Services.ww.registerNotification(winObserver);
|
|
}),
|
|
timeout,
|
|
);
|
|
}
|
|
|
|
export async function waitForNoteWindow() {
|
|
return await waitForWindow("chrome://zotero/content/note.xhtml");
|
|
}
|