mock-violentmonkey
Version:
Mock violentmonkey's globals for testing userscripts
106 lines • 3.48 kB
JavaScript
import { VMStorage } from '../vm-storage.js';
var NotificationStates;
(function (NotificationStates) {
NotificationStates[NotificationStates["visible"] = 0] = "visible";
NotificationStates[NotificationStates["removed"] = 1] = "removed";
})(NotificationStates || (NotificationStates = {}));
const notifications = new VMStorage(() => new Set());
class NotificationHandler {
text;
title;
image;
onClick;
onDone;
state = NotificationStates.visible;
constructor(options) {
({ text: this.text, title: this.title, image: this.image } = options);
// Don't leak `this`
this.onDone = () => {
options.ondone?.call(undefined);
};
this.onClick = () => {
options.onclick?.call(undefined);
};
notifications.get(true).add(this);
}
click = () => {
if (this.state !== NotificationStates.visible) {
return;
}
this.onClick();
this.cleanUp();
this.onDone();
};
close = () => {
if (this.state !== NotificationStates.visible) {
return;
}
this.cleanUp();
this.onDone();
};
remove = async () => new Promise(resolve => {
if (this.state === NotificationStates.visible) {
resolve(true);
}
this.cleanUp();
});
cleanUp = () => {
notifications.get(false)?.delete(this);
this.state = NotificationStates.removed;
};
}
const notification = (text, title, image, onclick) => {
const options = typeof text === 'object'
? text
: {
text,
title,
image,
onclick,
};
if (!options.text) {
throw new Error('GM_notification: `text` is required!');
}
const notificationHandler = new NotificationHandler(options);
return {
remove: notificationHandler.remove,
};
};
const valueMatchesSelector = (value, selector) => selector === undefined || selector === value;
const selectorKeys = ['text', 'image', 'title'];
const findNotificationsBySelectors = (selectors) => {
const allNotifications = notifications.get(false);
if (!allNotifications) {
return [];
}
const result = [];
for (const notification of allNotifications) {
if (selectorKeys.every(key => valueMatchesSelector(notification[key], selectors[key]))) {
result.push(notification);
}
}
return result;
};
const findNotifications = (selectors) => {
const getNotifications = () => findNotificationsBySelectors(selectors);
const curriedNotificationFunctionCaller = (key) => () => {
for (const notification of getNotifications()) {
void notification[key]();
}
};
return {
/** Remove all notifications matching the selectors */
remove: curriedNotificationFunctionCaller('remove'),
/** Click all notifications matching the selectors */
click: curriedNotificationFunctionCaller('click'),
/** Close all notifications matching the selectors */
close: curriedNotificationFunctionCaller('close'),
/** Count the amount of notifications matching the selectors */
count: () => getNotifications().length,
};
};
export { notification as GM_notification, findNotifications };
Object.defineProperty(globalThis, 'GM_notification', {
value: notification,
});
//# sourceMappingURL=notification.js.map