mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 16:20:53 +08:00

* update wml events to be parseable * [v3] Rename `CustomEvent` to `WailsEvent` to prevent clashing with the standard JS `CustomEvent` object --------- Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
194 lines
5.2 KiB
JavaScript
194 lines
5.2 KiB
JavaScript
/*
|
|
_ __ _ __
|
|
| | / /___ _(_) /____
|
|
| | /| / / __ `/ / / ___/
|
|
| |/ |/ / /_/ / / (__ )
|
|
|__/|__/\__,_/_/_/____/
|
|
The electron alternative for Go
|
|
(c) Lea Anthony 2019-present
|
|
*/
|
|
|
|
/* jshint esversion: 9 */
|
|
|
|
/**
|
|
* @typedef {import("./api/types").WailsEvent} WailsEvent
|
|
*/
|
|
|
|
import {newRuntimeCaller} from "./runtime";
|
|
|
|
let call = newRuntimeCaller("events");
|
|
|
|
/**
|
|
* The Listener class defines a listener! :-)
|
|
*
|
|
* @class Listener
|
|
*/
|
|
class Listener {
|
|
/**
|
|
* Creates an instance of Listener.
|
|
* @param {string} eventName
|
|
* @param {function} callback
|
|
* @param {number} maxCallbacks
|
|
* @memberof Listener
|
|
*/
|
|
constructor(eventName, callback, maxCallbacks) {
|
|
this.eventName = eventName;
|
|
// Default of -1 means infinite
|
|
this.maxCallbacks = maxCallbacks || -1;
|
|
// Callback invokes the callback with the given data
|
|
// Returns true if this listener should be destroyed
|
|
this.Callback = (data) => {
|
|
callback(data);
|
|
// If maxCallbacks is infinite, return false (do not destroy)
|
|
if (this.maxCallbacks === -1) {
|
|
return false;
|
|
}
|
|
// Decrement maxCallbacks. Return true if now 0, otherwise false
|
|
this.maxCallbacks -= 1;
|
|
return this.maxCallbacks === 0;
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* WailsEvent defines a custom event. It is passed to event listeners.
|
|
*
|
|
* @class WailsEvent
|
|
* @property {string} name - Name of the event
|
|
* @property {any} data - Data associated with the event
|
|
*/
|
|
export class WailsEvent {
|
|
/**
|
|
* Creates an instance of WailsEvent.
|
|
* @param {string} name - Name of the event
|
|
* @param {any=null} data - Data associated with the event
|
|
* @memberof WailsEvent
|
|
*/
|
|
constructor(name, data = null) {
|
|
this.name = name;
|
|
this.data = data;
|
|
}
|
|
}
|
|
|
|
export const eventListeners = new Map();
|
|
|
|
/**
|
|
* Registers an event listener that will be invoked `maxCallbacks` times before being destroyed
|
|
*
|
|
* @export
|
|
* @param {string} eventName
|
|
* @param {function(WailsEvent): void} callback
|
|
* @param {number} maxCallbacks
|
|
* @returns {function} A function to cancel the listener
|
|
*/
|
|
export function OnMultiple(eventName, callback, maxCallbacks) {
|
|
let listeners = eventListeners.get(eventName) || [];
|
|
const thisListener = new Listener(eventName, callback, maxCallbacks);
|
|
listeners.push(thisListener);
|
|
eventListeners.set(eventName, listeners);
|
|
return () => listenerOff(thisListener);
|
|
}
|
|
|
|
/**
|
|
* Registers an event listener that will be invoked every time the event is emitted
|
|
*
|
|
* @export
|
|
* @param {string} eventName
|
|
* @param {function(WailsEvent): void} callback
|
|
* @returns {function} A function to cancel the listener
|
|
*/
|
|
export function On(eventName, callback) {
|
|
return OnMultiple(eventName, callback, -1);
|
|
}
|
|
|
|
/**
|
|
* Registers an event listener that will be invoked once then destroyed
|
|
*
|
|
* @export
|
|
* @param {string} eventName
|
|
* @param {function(WailsEvent): void} callback
|
|
@returns {function} A function to cancel the listener
|
|
*/
|
|
export function Once(eventName, callback) {
|
|
return OnMultiple(eventName, callback, 1);
|
|
}
|
|
|
|
/**
|
|
* listenerOff unregisters a listener previously registered with On
|
|
*
|
|
* @param {Listener} listener
|
|
*/
|
|
function listenerOff(listener) {
|
|
const eventName = listener.eventName;
|
|
// Remove local listener
|
|
let listeners = eventListeners.get(eventName).filter(l => l !== listener);
|
|
if (listeners.length === 0) {
|
|
eventListeners.delete(eventName);
|
|
} else {
|
|
eventListeners.set(eventName, listeners);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* dispatches an event to all listeners
|
|
*
|
|
* @export
|
|
* @param {WailsEvent} event
|
|
*/
|
|
export function dispatchWailsEvent(event) {
|
|
console.log("dispatching event: ", {event});
|
|
let listeners = eventListeners.get(event.name);
|
|
if (listeners) {
|
|
// iterate listeners and call callback. If callback returns true, remove listener
|
|
let toRemove = [];
|
|
listeners.forEach(listener => {
|
|
let remove = listener.Callback(event);
|
|
if (remove) {
|
|
toRemove.push(listener);
|
|
}
|
|
});
|
|
// remove listeners
|
|
if (toRemove.length > 0) {
|
|
listeners = listeners.filter(l => !toRemove.includes(l));
|
|
if (listeners.length === 0) {
|
|
eventListeners.delete(event.name);
|
|
} else {
|
|
eventListeners.set(event.name, listeners);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Off unregisters a listener previously registered with On,
|
|
* optionally multiple listeners can be unregistered via `additionalEventNames`
|
|
*
|
|
[v3 CHANGE] Off only unregisters listeners within the current window
|
|
*
|
|
* @param {string} eventName
|
|
* @param {...string} additionalEventNames
|
|
*/
|
|
export function Off(eventName, ...additionalEventNames) {
|
|
let eventsToRemove = [eventName, ...additionalEventNames];
|
|
eventsToRemove.forEach(eventName => {
|
|
eventListeners.delete(eventName);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* OffAll unregisters all listeners
|
|
* [v3 CHANGE] OffAll only unregisters listeners within the current window
|
|
*
|
|
*/
|
|
export function OffAll() {
|
|
eventListeners.clear();
|
|
}
|
|
|
|
/**
|
|
* Emit an event
|
|
* @param {WailsEvent} event The event to emit
|
|
*/
|
|
export function Emit(event) {
|
|
void call("Emit", event);
|
|
} |