]> BookStack Code Mirror - bookstack/blob - resources/js/services/events.ts
Tests: Updated comment test to account for new editor usage
[bookstack] / resources / js / services / events.ts
1 import {HttpError} from "./http";
2
3 type Listener = (data: any) => void;
4
5 export class EventManager {
6     protected listeners: Record<string, Listener[]> = {};
7     protected stack: {name: string, data: {}}[] = [];
8
9     /**
10      * Emit a custom event for any handlers to pick-up.
11      */
12     emit(eventName: string, eventData: {} = {}): void {
13         this.stack.push({name: eventName, data: eventData});
14
15         const listenersToRun = this.listeners[eventName] || [];
16         for (const listener of listenersToRun) {
17             listener(eventData);
18         }
19     }
20
21     /**
22      * Listen to a custom event and run the given callback when that event occurs.
23      */
24     listen<T>(eventName: string, callback: (data: T) => void): void {
25         if (typeof this.listeners[eventName] === 'undefined') this.listeners[eventName] = [];
26         this.listeners[eventName].push(callback);
27     }
28
29     /**
30      * Remove an event listener which is using the given callback for the given event name.
31      */
32     remove(eventName: string, callback: Listener): void {
33         const listeners = this.listeners[eventName] || [];
34         const index = listeners.indexOf(callback);
35         if (index !== -1) {
36             listeners.splice(index, 1);
37         }
38     }
39
40     /**
41      * Emit an event for public use.
42      * Sends the event via the native DOM event handling system.
43      */
44     emitPublic(targetElement: Element, eventName: string, eventData: {}): void {
45         const event = new CustomEvent(eventName, {
46             detail: eventData,
47             bubbles: true,
48         });
49         targetElement.dispatchEvent(event);
50     }
51
52     /**
53      * Emit a success event with the provided message.
54      */
55     success(message: string): void {
56         this.emit('success', message);
57     }
58
59     /**
60      * Emit an error event with the provided message.
61      */
62     error(message: string): void {
63         this.emit('error', message);
64     }
65
66     /**
67      * Notify of standard server-provided validation errors.
68      */
69     showValidationErrors(responseErr: HttpError): void {
70         if (responseErr.status === 422 && responseErr.data) {
71             const message = Object.values(responseErr.data).flat().join('\n');
72             this.error(message);
73         }
74     }
75
76     /**
77      * Notify standard server-provided error messages.
78      */
79     showResponseError(responseErr: {status?: number, data?: Record<any, any>}|HttpError): void {
80         if (!responseErr.status) return;
81         if (responseErr.status >= 400 && typeof responseErr.data === 'object' && responseErr.data.message) {
82             this.error(responseErr.data.message);
83         }
84     }
85 }