x4js 2.0.35 → 2.1.0-manual
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -21
- package/package.json +39 -26
- package/src/components/base.scss +25 -89
- package/src/components/boxes/boxes.module.scss +54 -54
- package/src/components/boxes/boxes.ts +513 -513
- package/src/components/breadcrumb/breadcrumb.scss +56 -56
- package/src/components/breadcrumb/breadcrumb.ts +93 -93
- package/src/components/btngroup/btngroup.module.scss +40 -40
- package/src/components/btngroup/btngroup.ts +152 -152
- package/src/components/button/button.module.scss +172 -172
- package/src/components/button/button.ts +232 -232
- package/src/components/calendar/calendar.module.scss +162 -162
- package/src/components/calendar/calendar.ts +326 -326
- package/src/components/canvas/canvas.module.scss +24 -24
- package/src/components/canvas/canvas.ts +195 -195
- package/src/components/canvas/canvas_ex.ts +275 -275
- package/src/components/checkbox/check.svg +3 -3
- package/src/components/checkbox/checkbox.module.scss +141 -141
- package/src/components/checkbox/checkbox.ts +139 -139
- package/src/components/colorinput/colorinput.module.scss +64 -64
- package/src/components/colorinput/colorinput.ts +90 -90
- package/src/components/colorpicker/colorpicker.module.scss +132 -132
- package/src/components/colorpicker/colorpicker.ts +481 -481
- package/src/components/combobox/combobox.module.scss +145 -145
- package/src/components/combobox/combobox.ts +282 -282
- package/src/components/combobox/updown.svg +3 -3
- package/src/components/components.ts +45 -44
- package/src/components/dialog/dialog.module.scss +103 -105
- package/src/components/dialog/dialog.ts +233 -233
- package/src/components/filedrop/filedrop.module.scss +69 -69
- package/src/components/filedrop/filedrop.ts +130 -130
- package/src/components/form/form.module.scss +38 -38
- package/src/components/form/form.ts +172 -172
- package/src/components/gridview/gridview.module.scss +323 -337
- package/src/components/gridview/gridview.ts +1276 -1316
- package/src/components/header/header.module.scss +40 -40
- package/src/components/header/header.ts +141 -141
- package/src/components/icon/icon.module.scss +32 -32
- package/src/components/icon/icon.ts +165 -165
- package/src/components/image/image.module.scss +27 -27
- package/src/components/image/image.ts +168 -168
- package/src/components/input/input.module.scss +74 -74
- package/src/components/input/input.ts +537 -537
- package/src/components/keyboard/keyboard.module.scss +136 -136
- package/src/components/keyboard/keyboard.ts +549 -549
- package/src/components/label/label.module.scss +90 -91
- package/src/components/label/label.ts +101 -101
- package/src/components/link/link.module.scss +44 -44
- package/src/components/link/link.ts +87 -87
- package/src/components/listbox/listbox.module.scss +179 -179
- package/src/components/listbox/listbox.ts +596 -596
- package/src/components/menu/menu.module.scss +128 -128
- package/src/components/menu/menu.ts +174 -174
- package/src/components/messages/messages.module.scss +92 -146
- package/src/components/messages/messages.ts +237 -303
- package/src/components/normalize.scss +391 -391
- package/src/components/notification/notification.module.scss +83 -83
- package/src/components/notification/notification.ts +107 -107
- package/src/components/panel/panel.module.scss +66 -71
- package/src/components/panel/panel.ts +57 -57
- package/src/components/popup/popup.module.scss +51 -51
- package/src/components/popup/popup.ts +457 -457
- package/src/components/progress/progress.module.scss +56 -56
- package/src/components/progress/progress.ts +43 -43
- package/src/components/propgrid/progrid.module.scss +111 -111
- package/src/components/propgrid/propgrid.ts +300 -300
- package/src/components/propgrid/updown.svg +3 -3
- package/src/components/radio/radio.module.scss +163 -163
- package/src/components/radio/radio.svg +3 -3
- package/src/components/radio/radio.ts +141 -141
- package/src/components/rating/rating.module.scss +22 -22
- package/src/components/rating/rating.ts +131 -131
- package/src/components/select/select.module.scss +8 -8
- package/src/components/select/select.ts +134 -134
- package/src/components/shared.scss +141 -71
- package/src/components/sizers/sizer.module.scss +90 -112
- package/src/components/sizers/sizer.ts +131 -155
- package/src/components/slider/slider.module.scss +117 -117
- package/src/components/slider/slider.ts +197 -197
- package/src/components/spreadsheet/spreadsheet.module.scss +307 -307
- package/src/components/spreadsheet/spreadsheet.ts +1223 -1223
- package/src/components/switch/switch.module.scss +126 -126
- package/src/components/switch/switch.ts +61 -61
- package/src/components/tabs/tabs.module.scss +46 -67
- package/src/components/tabs/tabs.ts +229 -234
- package/src/components/textarea/textarea.module.scss +63 -63
- package/src/components/textarea/textarea.ts +131 -131
- package/src/components/textedit/textedit.module.scss +115 -115
- package/src/components/textedit/textedit.ts +122 -122
- package/src/components/themes.scss +90 -90
- package/src/components/tickline/tickline.module.scss +25 -25
- package/src/components/tickline/tickline.ts +81 -81
- package/src/components/tooltips/tooltips.scss +71 -71
- package/src/components/tooltips/tooltips.ts +120 -120
- package/src/components/treeview/treeview.module.scss +192 -192
- package/src/components/treeview/treeview.ts +484 -484
- package/src/components/viewport/viewport.module.scss +31 -31
- package/src/components/viewport/viewport.ts +41 -41
- package/src/core/component.ts +1299 -1299
- package/src/core/core_application.ts +361 -361
- package/src/core/core_colors.ts +512 -512
- package/src/core/core_data.ts +1297 -1310
- package/src/core/core_dom.ts +481 -481
- package/src/core/core_dragdrop.ts +225 -225
- package/src/core/core_element.ts +221 -221
- package/src/core/core_events.ts +214 -214
- package/src/core/core_i18n.ts +395 -395
- package/src/core/core_pdf.ts +454 -454
- package/src/core/core_react.ts +78 -78
- package/src/core/core_router.ts +296 -296
- package/src/core/core_state.ts +62 -62
- package/src/core/core_styles.ts +213 -213
- package/src/core/core_svg.ts +1042 -1042
- package/src/core/core_tools.ts +996 -996
- package/src/types/scss.d.ts +4 -4
- package/src/types/x4react.d.ts +8 -8
- package/src/x4.scss +19 -19
- package/src/x4.ts +36 -36
- package/src/x4tsx.d.ts +26 -26
- package/.vscode/launch.json +0 -14
- package/.vscode/settings.json +0 -2
- package/demo/assets/house-light.svg +0 -1
- package/demo/assets/radio.svg +0 -4
- package/demo/index.html +0 -12
- package/demo/main.scss +0 -23
- package/demo/main.ts +0 -324
- package/demo/package.json +0 -26
- package/demo/scss.d.ts +0 -4
- package/demo/svg.d.ts +0 -1
- package/demo/tsconfig.json +0 -14
- package/src/components/gridview/folder-open.svg +0 -1
- package/src/components/messages/spinner.svg +0 -1
- package/src/x4.d.ts +0 -10
- package/tsconfig.json +0 -11
package/src/core/core_element.ts
CHANGED
|
@@ -1,222 +1,222 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ___ ___ __
|
|
3
|
-
* \ \/ / / _
|
|
4
|
-
* \ / /_| |_
|
|
5
|
-
* / \____ _|
|
|
6
|
-
* /__/\__\ |_|
|
|
7
|
-
*
|
|
8
|
-
* @file core_element.ts
|
|
9
|
-
* @author Etienne Cochard
|
|
10
|
-
*
|
|
11
|
-
* @copyright (c) 2024 R-libre ingenierie
|
|
12
|
-
*
|
|
13
|
-
* Use of this source code is governed by an MIT-style license
|
|
14
|
-
* that can be found in the LICENSE file or at https://opensource.org/licenses/MIT.
|
|
15
|
-
**/
|
|
16
|
-
|
|
17
|
-
import { EventMap, EventSource } from './core_events';
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* CoreElement
|
|
22
|
-
*
|
|
23
|
-
* A lightweight base class that provides two orthogonal utilities commonly needed by UI
|
|
24
|
-
* or domain objects:
|
|
25
|
-
* 1) Named timers (wraps setTimeout / setInterval by name so they can be started, stopped,
|
|
26
|
-
* and cleared by string identifier), and
|
|
27
|
-
* 2) A typed eventing surface (lazy-initialised EventSource) for attaching, detaching and
|
|
28
|
-
* firing events.
|
|
29
|
-
*
|
|
30
|
-
* The class is generic over an EventMap `E` which maps event name keys to the payload
|
|
31
|
-
* type for that event. This enables compile-time type safety for listeners and fired events.
|
|
32
|
-
*
|
|
33
|
-
* Template parameters:
|
|
34
|
-
* @template E - An {@link EventMap}-shaped type that maps event keys to the event payload types.
|
|
35
|
-
*
|
|
36
|
-
* Timer semantics:
|
|
37
|
-
* - Timers are referenced by a string `name`. Each instance of CoreElement maintains its own
|
|
38
|
-
* map of timers.
|
|
39
|
-
* - Starting a timer with a name that is already present will stop the previous timer first.
|
|
40
|
-
* - setTimeout(name, ms, callback) creates a single-shot timer (uses global setTimeout).
|
|
41
|
-
* - setInterval(name, ms, callback) creates a repeating timer (uses global setInterval).
|
|
42
|
-
* - clearTimeout(name) and clearInterval(name) both stop and remove the timer with the given
|
|
43
|
-
* name (they are aliases for the same internal stop logic).
|
|
44
|
-
* - clearTimeouts() will stop and remove all timers currently tracked by the instance.
|
|
45
|
-
* - The underlying timer handles are encapsulated; callers only interact via the string name.
|
|
46
|
-
*
|
|
47
|
-
* Event semantics:
|
|
48
|
-
* - Event support is provided via a lazily-initialised EventSource instance internal to the
|
|
49
|
-
* CoreElement. The EventSource is created on first use (first call to on()).
|
|
50
|
-
* - on(name, listener) registers a listener for the given event name and returns a small
|
|
51
|
-
* subscription object exposing an off() method for convenience.
|
|
52
|
-
* - off(name, listener) removes a previously-registered listener (no-op if there is no
|
|
53
|
-
* EventSource or listener).
|
|
54
|
-
* - fire(name, ev) will dispatch the given payload to all listeners registered for that
|
|
55
|
-
* event name (no-op if there is no EventSource).
|
|
56
|
-
* - Listener and event payload types are enforced by the generic `E`.
|
|
57
|
-
*
|
|
58
|
-
* Threading / reentrancy / error handling:
|
|
59
|
-
* - Timer callbacks execute via the platform timer mechanisms (setTimeout/setInterval). Any
|
|
60
|
-
* exceptions thrown by callbacks will propagate according to the environment's timer
|
|
61
|
-
* semantics (typically uncaught unless handled by the callback).
|
|
62
|
-
* - The class uses console.assert to validate non-null listeners on public attach/detach
|
|
63
|
-
* methods; callers should avoid passing undefined/null listeners.
|
|
64
|
-
* Example:
|
|
65
|
-
* ```ts
|
|
66
|
-
* // Strongly-typed events
|
|
67
|
-
* interface MyEvents { loaded: { ok: boolean }, tick: number }
|
|
68
|
-
* class MyElement extends CoreElement<MyEvents> {}
|
|
69
|
-
*
|
|
70
|
-
* const el = new MyElement();
|
|
71
|
-
* const sub = el.on("loaded", e => console.log(e.ok));
|
|
72
|
-
* el.fire("loaded", { ok: true });
|
|
73
|
-
* sub.off(); // convenience to remove listener
|
|
74
|
-
*
|
|
75
|
-
* // Timers
|
|
76
|
-
* el.setInterval("poll", 1000, () => el.fire("tick", Date.now()));
|
|
77
|
-
* el.clearInterval("poll");
|
|
78
|
-
* ```
|
|
79
|
-
*/
|
|
80
|
-
export class CoreElement<E extends EventMap = EventMap> {
|
|
81
|
-
|
|
82
|
-
#events: EventSource<E>;
|
|
83
|
-
#timers: Map<string, Function>;
|
|
84
|
-
|
|
85
|
-
private __startTimer( name: string, ms: number, repeat: boolean, callback: ( ) => void ) {
|
|
86
|
-
if (!this.#timers) {
|
|
87
|
-
this.#timers = new Map();
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
this.__stopTimer(name);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const id = (repeat ? setInterval : setTimeout)( callback, ms );
|
|
94
|
-
|
|
95
|
-
this.#timers.set(name, () => {
|
|
96
|
-
(repeat ? clearInterval : clearTimeout)(id);
|
|
97
|
-
this.#timers.delete(name)
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
private __stopTimer( name: string ) {
|
|
102
|
-
const clear = this.#timers?.get(name);
|
|
103
|
-
if (clear) { clear(); }
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Sets a timeout that executes a callback function after a specified delay.
|
|
108
|
-
* If a timeout with the same name already exists, it will be cleared before the new one is set.
|
|
109
|
-
* @param name - A unique string identifier for this timeout.
|
|
110
|
-
* @param ms - The delay in milliseconds before the callback is executed.
|
|
111
|
-
* @param callback - The function to execute after the delay.
|
|
112
|
-
*/
|
|
113
|
-
|
|
114
|
-
setTimeout( name: string, ms: number, callback: () => void ) {
|
|
115
|
-
this.__startTimer( name, ms, false, callback );
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Clears a previously set timeout.
|
|
120
|
-
* @param name - The name of the timeout to clear.
|
|
121
|
-
* @link setTimeout
|
|
122
|
-
*/
|
|
123
|
-
|
|
124
|
-
clearTimeout( name: string ) {
|
|
125
|
-
this.__stopTimer( name );
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Sets an interval that repeatedly executes a callback function after a specified delay.
|
|
130
|
-
* If a timeout with the same name already exists, it will be cleared before the new one is set.
|
|
131
|
-
* @param name - A unique string identifier for this timeout.
|
|
132
|
-
* @param ms - The delay in milliseconds before the callback is executed.
|
|
133
|
-
* @param callback - The function to execute after the delay.
|
|
134
|
-
*/
|
|
135
|
-
|
|
136
|
-
setInterval( name: string, ms: number, callback: ( ) => void ) {
|
|
137
|
-
this.__startTimer( name, ms, true, callback );
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Clears a previously set interval.
|
|
142
|
-
* @param name - The name of the interval to clear.
|
|
143
|
-
* @link setInterval
|
|
144
|
-
*/
|
|
145
|
-
|
|
146
|
-
clearInterval( name: string ) {
|
|
147
|
-
this.__stopTimer( name );
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Clears all timeouts and intervals currently managed by this instance.
|
|
152
|
-
* This stops all scheduled callbacks and removes their references.
|
|
153
|
-
* @link setTimeout
|
|
154
|
-
*/
|
|
155
|
-
clearTimeouts( ) {
|
|
156
|
-
for( const [id,val] of this.#timers ) {
|
|
157
|
-
val( );
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
this.#timers.clear( );
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// :: EVENTS ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Registers an event listener for a specific event name.
|
|
167
|
-
* The listener will be invoked when an event with the given name is fired.
|
|
168
|
-
* Returns an object with an `off()` method, which can be used to conveniently remove this specific listener.
|
|
169
|
-
* @param name - The name of the event to listen for.
|
|
170
|
-
* @param listener - The callback function to execute when the event is fired.
|
|
171
|
-
* @returns An object containing an `off()` method to unsubscribe the listener.
|
|
172
|
-
* @link fire
|
|
173
|
-
* attach to an event
|
|
174
|
-
*/
|
|
175
|
-
|
|
176
|
-
on<K extends keyof E>( name: K, listener: ( ev: E[K] ) => void ) {
|
|
177
|
-
console.assert( listener!==undefined && listener!==null );
|
|
178
|
-
|
|
179
|
-
if( !this.#events ) {
|
|
180
|
-
this.#events = new EventSource( this );
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
this.#events.addListener( name, listener );
|
|
184
|
-
return {
|
|
185
|
-
off: ( ) => {
|
|
186
|
-
this.#events.removeListener( name, listener );
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Removes a previously registered event listener.
|
|
193
|
-
* If the listener was not found or no events were registered, this method does nothing.
|
|
194
|
-
* @param name - The name of the event from which to remove the listener.
|
|
195
|
-
* @param listener - The specific listener function to remove.
|
|
196
|
-
* @link on
|
|
197
|
-
* @link fire
|
|
198
|
-
*/
|
|
199
|
-
|
|
200
|
-
off<K extends keyof E>( name: K, listener: ( ev: E[K] ) => void ) {
|
|
201
|
-
console.assert( listener!==undefined && listener!==null );
|
|
202
|
-
|
|
203
|
-
if( this.#events ) {
|
|
204
|
-
this.#events.removeListener( name, listener );
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Dispatches an event with a given name and payload to all registered listeners.
|
|
210
|
-
* If no listeners are registered for the event name, or if no EventSource has been initialized, this method does nothing.
|
|
211
|
-
* @param name - The name of the event to fire.
|
|
212
|
-
* @param ev - The payload (event object) to pass to the listeners.
|
|
213
|
-
* @link on
|
|
214
|
-
* @link off
|
|
215
|
-
*/
|
|
216
|
-
|
|
217
|
-
fire<K extends keyof E>( name: K, ev: E[K] ) {
|
|
218
|
-
if( this.#events ) {
|
|
219
|
-
this.#events.fire( name, ev );
|
|
220
|
-
}
|
|
221
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* ___ ___ __
|
|
3
|
+
* \ \/ / / _
|
|
4
|
+
* \ / /_| |_
|
|
5
|
+
* / \____ _|
|
|
6
|
+
* /__/\__\ |_|
|
|
7
|
+
*
|
|
8
|
+
* @file core_element.ts
|
|
9
|
+
* @author Etienne Cochard
|
|
10
|
+
*
|
|
11
|
+
* @copyright (c) 2024 R-libre ingenierie
|
|
12
|
+
*
|
|
13
|
+
* Use of this source code is governed by an MIT-style license
|
|
14
|
+
* that can be found in the LICENSE file or at https://opensource.org/licenses/MIT.
|
|
15
|
+
**/
|
|
16
|
+
|
|
17
|
+
import { EventMap, EventSource } from './core_events';
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* CoreElement
|
|
22
|
+
*
|
|
23
|
+
* A lightweight base class that provides two orthogonal utilities commonly needed by UI
|
|
24
|
+
* or domain objects:
|
|
25
|
+
* 1) Named timers (wraps setTimeout / setInterval by name so they can be started, stopped,
|
|
26
|
+
* and cleared by string identifier), and
|
|
27
|
+
* 2) A typed eventing surface (lazy-initialised EventSource) for attaching, detaching and
|
|
28
|
+
* firing events.
|
|
29
|
+
*
|
|
30
|
+
* The class is generic over an EventMap `E` which maps event name keys to the payload
|
|
31
|
+
* type for that event. This enables compile-time type safety for listeners and fired events.
|
|
32
|
+
*
|
|
33
|
+
* Template parameters:
|
|
34
|
+
* @template E - An {@link EventMap}-shaped type that maps event keys to the event payload types.
|
|
35
|
+
*
|
|
36
|
+
* Timer semantics:
|
|
37
|
+
* - Timers are referenced by a string `name`. Each instance of CoreElement maintains its own
|
|
38
|
+
* map of timers.
|
|
39
|
+
* - Starting a timer with a name that is already present will stop the previous timer first.
|
|
40
|
+
* - setTimeout(name, ms, callback) creates a single-shot timer (uses global setTimeout).
|
|
41
|
+
* - setInterval(name, ms, callback) creates a repeating timer (uses global setInterval).
|
|
42
|
+
* - clearTimeout(name) and clearInterval(name) both stop and remove the timer with the given
|
|
43
|
+
* name (they are aliases for the same internal stop logic).
|
|
44
|
+
* - clearTimeouts() will stop and remove all timers currently tracked by the instance.
|
|
45
|
+
* - The underlying timer handles are encapsulated; callers only interact via the string name.
|
|
46
|
+
*
|
|
47
|
+
* Event semantics:
|
|
48
|
+
* - Event support is provided via a lazily-initialised EventSource instance internal to the
|
|
49
|
+
* CoreElement. The EventSource is created on first use (first call to on()).
|
|
50
|
+
* - on(name, listener) registers a listener for the given event name and returns a small
|
|
51
|
+
* subscription object exposing an off() method for convenience.
|
|
52
|
+
* - off(name, listener) removes a previously-registered listener (no-op if there is no
|
|
53
|
+
* EventSource or listener).
|
|
54
|
+
* - fire(name, ev) will dispatch the given payload to all listeners registered for that
|
|
55
|
+
* event name (no-op if there is no EventSource).
|
|
56
|
+
* - Listener and event payload types are enforced by the generic `E`.
|
|
57
|
+
*
|
|
58
|
+
* Threading / reentrancy / error handling:
|
|
59
|
+
* - Timer callbacks execute via the platform timer mechanisms (setTimeout/setInterval). Any
|
|
60
|
+
* exceptions thrown by callbacks will propagate according to the environment's timer
|
|
61
|
+
* semantics (typically uncaught unless handled by the callback).
|
|
62
|
+
* - The class uses console.assert to validate non-null listeners on public attach/detach
|
|
63
|
+
* methods; callers should avoid passing undefined/null listeners.
|
|
64
|
+
* Example:
|
|
65
|
+
* ```ts
|
|
66
|
+
* // Strongly-typed events
|
|
67
|
+
* interface MyEvents { loaded: { ok: boolean }, tick: number }
|
|
68
|
+
* class MyElement extends CoreElement<MyEvents> {}
|
|
69
|
+
*
|
|
70
|
+
* const el = new MyElement();
|
|
71
|
+
* const sub = el.on("loaded", e => console.log(e.ok));
|
|
72
|
+
* el.fire("loaded", { ok: true });
|
|
73
|
+
* sub.off(); // convenience to remove listener
|
|
74
|
+
*
|
|
75
|
+
* // Timers
|
|
76
|
+
* el.setInterval("poll", 1000, () => el.fire("tick", Date.now()));
|
|
77
|
+
* el.clearInterval("poll");
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export class CoreElement<E extends EventMap = EventMap> {
|
|
81
|
+
|
|
82
|
+
#events: EventSource<E>;
|
|
83
|
+
#timers: Map<string, Function>;
|
|
84
|
+
|
|
85
|
+
private __startTimer( name: string, ms: number, repeat: boolean, callback: ( ) => void ) {
|
|
86
|
+
if (!this.#timers) {
|
|
87
|
+
this.#timers = new Map();
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
this.__stopTimer(name);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const id = (repeat ? setInterval : setTimeout)( callback, ms );
|
|
94
|
+
|
|
95
|
+
this.#timers.set(name, () => {
|
|
96
|
+
(repeat ? clearInterval : clearTimeout)(id);
|
|
97
|
+
this.#timers.delete(name)
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
private __stopTimer( name: string ) {
|
|
102
|
+
const clear = this.#timers?.get(name);
|
|
103
|
+
if (clear) { clear(); }
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Sets a timeout that executes a callback function after a specified delay.
|
|
108
|
+
* If a timeout with the same name already exists, it will be cleared before the new one is set.
|
|
109
|
+
* @param name - A unique string identifier for this timeout.
|
|
110
|
+
* @param ms - The delay in milliseconds before the callback is executed.
|
|
111
|
+
* @param callback - The function to execute after the delay.
|
|
112
|
+
*/
|
|
113
|
+
|
|
114
|
+
setTimeout( name: string, ms: number, callback: () => void ) {
|
|
115
|
+
this.__startTimer( name, ms, false, callback );
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Clears a previously set timeout.
|
|
120
|
+
* @param name - The name of the timeout to clear.
|
|
121
|
+
* @link setTimeout
|
|
122
|
+
*/
|
|
123
|
+
|
|
124
|
+
clearTimeout( name: string ) {
|
|
125
|
+
this.__stopTimer( name );
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Sets an interval that repeatedly executes a callback function after a specified delay.
|
|
130
|
+
* If a timeout with the same name already exists, it will be cleared before the new one is set.
|
|
131
|
+
* @param name - A unique string identifier for this timeout.
|
|
132
|
+
* @param ms - The delay in milliseconds before the callback is executed.
|
|
133
|
+
* @param callback - The function to execute after the delay.
|
|
134
|
+
*/
|
|
135
|
+
|
|
136
|
+
setInterval( name: string, ms: number, callback: ( ) => void ) {
|
|
137
|
+
this.__startTimer( name, ms, true, callback );
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Clears a previously set interval.
|
|
142
|
+
* @param name - The name of the interval to clear.
|
|
143
|
+
* @link setInterval
|
|
144
|
+
*/
|
|
145
|
+
|
|
146
|
+
clearInterval( name: string ) {
|
|
147
|
+
this.__stopTimer( name );
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Clears all timeouts and intervals currently managed by this instance.
|
|
152
|
+
* This stops all scheduled callbacks and removes their references.
|
|
153
|
+
* @link setTimeout
|
|
154
|
+
*/
|
|
155
|
+
clearTimeouts( ) {
|
|
156
|
+
for( const [id,val] of this.#timers ) {
|
|
157
|
+
val( );
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
this.#timers.clear( );
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// :: EVENTS ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Registers an event listener for a specific event name.
|
|
167
|
+
* The listener will be invoked when an event with the given name is fired.
|
|
168
|
+
* Returns an object with an `off()` method, which can be used to conveniently remove this specific listener.
|
|
169
|
+
* @param name - The name of the event to listen for.
|
|
170
|
+
* @param listener - The callback function to execute when the event is fired.
|
|
171
|
+
* @returns An object containing an `off()` method to unsubscribe the listener.
|
|
172
|
+
* @link fire
|
|
173
|
+
* attach to an event
|
|
174
|
+
*/
|
|
175
|
+
|
|
176
|
+
on<K extends keyof E>( name: K, listener: ( ev: E[K] ) => void ) {
|
|
177
|
+
console.assert( listener!==undefined && listener!==null );
|
|
178
|
+
|
|
179
|
+
if( !this.#events ) {
|
|
180
|
+
this.#events = new EventSource( this );
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
this.#events.addListener( name, listener );
|
|
184
|
+
return {
|
|
185
|
+
off: ( ) => {
|
|
186
|
+
this.#events.removeListener( name, listener );
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Removes a previously registered event listener.
|
|
193
|
+
* If the listener was not found or no events were registered, this method does nothing.
|
|
194
|
+
* @param name - The name of the event from which to remove the listener.
|
|
195
|
+
* @param listener - The specific listener function to remove.
|
|
196
|
+
* @link on
|
|
197
|
+
* @link fire
|
|
198
|
+
*/
|
|
199
|
+
|
|
200
|
+
off<K extends keyof E>( name: K, listener: ( ev: E[K] ) => void ) {
|
|
201
|
+
console.assert( listener!==undefined && listener!==null );
|
|
202
|
+
|
|
203
|
+
if( this.#events ) {
|
|
204
|
+
this.#events.removeListener( name, listener );
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Dispatches an event with a given name and payload to all registered listeners.
|
|
210
|
+
* If no listeners are registered for the event name, or if no EventSource has been initialized, this method does nothing.
|
|
211
|
+
* @param name - The name of the event to fire.
|
|
212
|
+
* @param ev - The payload (event object) to pass to the listeners.
|
|
213
|
+
* @link on
|
|
214
|
+
* @link off
|
|
215
|
+
*/
|
|
216
|
+
|
|
217
|
+
fire<K extends keyof E>( name: K, ev: E[K] ) {
|
|
218
|
+
if( this.#events ) {
|
|
219
|
+
this.#events.fire( name, ev );
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
222
|
}
|