@@ -28,16 +28,19 @@ export interface EventHandlerOptions {
28
28
preventDefault : boolean ;
29
29
}
30
30
31
- /**
32
- * A config that specifies how to handle a particular event.
33
- */
31
+ /** A basic event handler. */
32
+ export type EventHandler < T extends Event > = ( event : T ) => void ;
33
+
34
+ /** A function that determines whether an event is to be handled. */
35
+ export type EventMatcher < T extends Event > = ( event : T ) => boolean ;
36
+
37
+ /** A config that specifies how to handle a particular event. */
34
38
export interface EventHandlerConfig < T extends Event > extends EventHandlerOptions {
35
- handler : ( event : T ) => boolean | void ;
39
+ matcher : EventMatcher < T > ;
40
+ handler : EventHandler < T > ;
36
41
}
37
42
38
- /**
39
- * Bit flag representation of the possible modifier keys that can be present on an event.
40
- */
43
+ /** Bit flag representation of the possible modifier keys that can be present on an event. */
41
44
export enum ModifierKey {
42
45
None = 0 ,
43
46
Ctrl = 0b1 ,
@@ -46,134 +49,40 @@ export enum ModifierKey {
46
49
Meta = 0b1000 ,
47
50
}
48
51
52
+ export type ModifierInputs = ModifierKey | ModifierKey [ ] ;
53
+
49
54
/**
50
55
* Abstract base class for all event managers.
51
56
*
52
57
* Event managers are designed to normalize how event handlers are authored and create a safety net
53
58
* for common event handling gotchas like remembering to call preventDefault or stopPropagation.
54
59
*/
55
60
export abstract class EventManager < T extends Event > {
56
- private _submanagers : EventManager < T > [ ] = [ ] ;
57
-
58
61
protected configs : EventHandlerConfig < T > [ ] = [ ] ;
59
- protected beforeFns : ( ( event : T ) => void ) [ ] = [ ] ;
60
- protected afterFns : ( ( event : T ) => void ) [ ] = [ ] ;
62
+ abstract options : EventHandlerOptions ;
61
63
62
- protected defaultHandlerOptions : EventHandlerOptions = {
63
- preventDefault : false ,
64
- stopPropagation : false ,
65
- } ;
64
+ /** Runs the handlers that match with the given event. */
65
+ handle ( event : T ) : void {
66
+ for ( const config of this . configs ) {
67
+ if ( config . matcher ( event ) ) {
68
+ config . handler ( event ) ;
66
69
67
- constructor ( defaultHandlerOptions ?: Partial < EventHandlerOptions > ) {
68
- this . defaultHandlerOptions = {
69
- ...this . defaultHandlerOptions ,
70
- ...defaultHandlerOptions ,
71
- } ;
72
- }
73
-
74
- /**
75
- * Composes together multiple event managers into a single event manager that delegates to the
76
- * individual managers.
77
- */
78
- static compose < T extends Event > ( ...managers : EventManager < T > [ ] ) {
79
- const composedManager = new GenericEventManager < T > ( ) ;
80
- composedManager . _submanagers = managers ;
81
- return composedManager ;
82
- }
70
+ if ( config . preventDefault ) {
71
+ event . preventDefault ( ) ;
72
+ }
83
73
84
- /**
85
- * Runs any handlers that have been configured to handle this event. If multiple handlers are
86
- * configured for this event, they are run in the order they were configured. Returns
87
- * `true` if the event has been handled, otherwise returns `undefined`.
88
- *
89
- * Note: the use of `undefined` instead of `false` in the unhandled case is necessary to avoid
90
- * accidentally preventing the default behavior on an unhandled event.
91
- */
92
- handle ( event : T ) : true | undefined {
93
- if ( ! this . isHandled ( event ) ) {
94
- return undefined ;
95
- }
96
- for ( const fn of this . beforeFns ) {
97
- fn ( event ) ;
98
- }
99
- for ( const submanager of this . _submanagers ) {
100
- submanager . handle ( event ) ;
101
- }
102
- for ( const config of this . getHandlersForKey ( event ) ) {
103
- config . handler ( event ) ;
104
- if ( config . stopPropagation ) {
105
- event . stopPropagation ( ) ;
74
+ if ( config . stopPropagation ) {
75
+ event . stopPropagation ( ) ;
76
+ }
106
77
}
107
- if ( config . preventDefault ) {
108
- event . preventDefault ( ) ;
109
- }
110
- }
111
- for ( const fn of this . afterFns ) {
112
- fn ( event ) ;
113
78
}
114
- return true ;
115
79
}
116
80
117
- /**
118
- * Configures the event manager to run a function immediately before it as about to handle
119
- * any event.
120
- */
121
- beforeHandling ( fn : ( event : T ) => void ) : this {
122
- this . beforeFns . push ( fn ) ;
123
- return this ;
124
- }
125
-
126
- /**
127
- * Configures the event manager to run a function immediately after it handles any event.
128
- */
129
- afterHandling ( fn : ( event : T ) => void ) : this {
130
- this . afterFns . push ( fn ) ;
131
- return this ;
132
- }
133
-
134
- /**
135
- * Configures the event manager to handle specific events. (See subclasses for more).
136
- */
81
+ /** Configures the event manager to handle specific events. (See subclasses for more). */
137
82
abstract on ( ...args : [ ...unknown [ ] ] ) : this;
138
-
139
- /**
140
- * Gets all of the handler configs that are applicable to the given event.
141
- */
142
- protected abstract getHandlersForKey ( event : T ) : EventHandlerConfig < T > [ ] ;
143
-
144
- /**
145
- * Checks whether this event manager is confugred to handle the given event.
146
- */
147
- protected isHandled ( event : T ) : boolean {
148
- return (
149
- this . getHandlersForKey ( event ) . length > 0 || this . _submanagers . some ( sm => sm . isHandled ( event ) )
150
- ) ;
151
- }
152
- }
153
-
154
- /**
155
- * A generic event manager that can work with any type of event.
156
- */
157
- export class GenericEventManager < T extends Event > extends EventManager < T > {
158
- /**
159
- * Configures this event manager to handle all events with the given handler.
160
- */
161
- on ( handler : ( event : T ) => boolean | void ) : this {
162
- this . configs . push ( {
163
- ...this . defaultHandlerOptions ,
164
- handler,
165
- } ) ;
166
- return this ;
167
- }
168
-
169
- getHandlersForKey ( _event : T ) : EventHandlerConfig < T > [ ] {
170
- return this . configs ;
171
- }
172
83
}
173
84
174
- /**
175
- * Gets bit flag representation of the modifier keys present on the given event.
176
- */
85
+ /** Gets bit flag representation of the modifier keys present on the given event. */
177
86
export function getModifiers ( event : EventWithModifiers ) : number {
178
87
return (
179
88
( + event . ctrlKey && ModifierKey . Ctrl ) |
@@ -187,7 +96,7 @@ export function getModifiers(event: EventWithModifiers): number {
187
96
* Checks if the given event has modifiers that are an exact match for any of the given modifier
188
97
* flag combinations.
189
98
*/
190
- export function hasModifiers ( event : EventWithModifiers , modifiers : number | number [ ] ) : boolean {
99
+ export function hasModifiers ( event : EventWithModifiers , modifiers : ModifierInputs ) : boolean {
191
100
const eventModifiers = getModifiers ( event ) ;
192
101
const modifiersList = Array . isArray ( modifiers ) ? modifiers : [ modifiers ] ;
193
102
return modifiersList . some ( modifiers => eventModifiers === modifiers ) ;
0 commit comments