Remove event config (#19237)
Dan Abramov committed
Jul 2, 2020 at 00:26 UTC
b6df4417c79c11cfb44f965fab55b573882b1d54
10 files changed
+124
-229
packages/react-dom/src/client/ReactDOMComponent.js
+1
-1
@@ -10,7 +10,7 @@
10
import {
11
registrationNameDependencies,
12
possibleRegistrationNames,
13
-} from '../events/EventPluginRegistry';
13
+} from '../events/EventRegistry';
14
import {canUseDOM} from 'shared/ExecutionEnvironment';
15
import invariant from 'shared/invariant';
16
import {
packages/react-dom/src/events/DOMEventProperties.js
+26
-50
@@ -12,8 +12,8 @@ import type {
12
TopLevelType,
13
DOMTopLevelEventType,
14
} from '../events/TopLevelEventTypes';
15
-import type {EventTypes} from '../events/PluginModuleType';
15
16
+import {registerTwoPhaseEvent} from './EventRegistry';
17
import * as DOMTopLevelEventTypes from './DOMTopLevelEventTypes';
18
import {
19
DiscreteEvent,
@@ -23,14 +23,6 @@ import {
23
24
import {enableCreateEventHandleAPI} from 'shared/ReactFeatureFlags';
25
26
-// Needed for SimpleEventPlugin, rather than
27
-// do it in two places, which duplicates logic
28
-// and increases the bundle size, we do it all
29
-// here once. If we remove or refactor the
30
-// SimpleEventPlugin, we should also remove or
31
-// update the below line.
32
-export const simpleEventPluginEventTypes: EventTypes = {};
33
-
26
export const topLevelEventsToReactNames: Map<
27
TopLevelType,
28
string | null,
@@ -152,23 +144,16 @@ const continuousPairsForSimpleEventPlugin = [
144
/**
145
* Turns
146
* ['abort', ...]
147
+ *
148
* into
156
- * eventTypes = {
157
- * 'abort': {
158
- * phasedRegistrationNames: {
159
- * bubbled: 'onAbort',
160
- * captured: 'onAbortCapture',
161
- * },
162
- * dependencies: [TOP_ABORT],
163
- * },
164
- * ...
165
- * };
149
+ *
150
* topLevelEventsToReactNames = new Map([
151
* [TOP_ABORT, 'onAbort'],
152
* ]);
153
+ *
154
+ * and registers them.
155
*/
170
-
171
-function processSimpleEventPluginPairsByPriority(
156
+function registerSimplePluginEventsAndSetTheirPriorities(
157
eventTypes: Array<DOMTopLevelEventType | string>,
158
priority: EventPriority,
159
): void {
@@ -182,23 +167,14 @@ function processSimpleEventPluginPairsByPriority(
167
const topEvent = ((eventTypes[i]: any): DOMTopLevelEventType);
168
const event = ((eventTypes[i + 1]: any): string);
169
const capitalizedEvent = event[0].toUpperCase() + event.slice(1);
185
- const onEvent = 'on' + capitalizedEvent;
186
-
187
- const config = {
188
- phasedRegistrationNames: {
189
- bubbled: onEvent,
190
- captured: onEvent + 'Capture',
191
- },
192
- dependencies: [topEvent],
193
- eventPriority: priority,
194
- };
170
+ const reactName = 'on' + capitalizedEvent;
171
eventPriorities.set(topEvent, priority);
196
- topLevelEventsToReactNames.set(topEvent, onEvent);
197
- simpleEventPluginEventTypes[event] = config;
172
+ topLevelEventsToReactNames.set(topEvent, reactName);
173
+ registerTwoPhaseEvent(reactName, [topEvent]);
174
}
175
}
176
201
-function processTopEventPairsByPriority(
177
+function setEventPriorities(
178
eventTypes: Array<DOMTopLevelEventType | string>,
179
priority: EventPriority,
180
): void {
@@ -207,22 +183,6 @@ function processTopEventPairsByPriority(
183
}
184
}
185
210
-// SimpleEventPlugin
211
-processSimpleEventPluginPairsByPriority(
212
- discreteEventPairsForSimpleEventPlugin,
213
- DiscreteEvent,
214
-);
215
-processSimpleEventPluginPairsByPriority(
216
- userBlockingPairsForSimpleEventPlugin,
217
- UserBlockingEvent,
218
-);
219
-processSimpleEventPluginPairsByPriority(
220
- continuousPairsForSimpleEventPlugin,
221
- ContinuousEvent,
222
-);
223
-// Not used by SimpleEventPlugin
224
-processTopEventPairsByPriority(otherDiscreteEvents, DiscreteEvent);
225
-
186
export function getEventPriorityForPluginSystem(
187
topLevelType: TopLevelType,
188
): EventPriority {
@@ -248,3 +208,19 @@ export function getEventPriorityForListenerSystem(
208
}
209
return ContinuousEvent;
210
}
211
+
212
+export function registerSimpleEvents() {
213
+ registerSimplePluginEventsAndSetTheirPriorities(
214
+ discreteEventPairsForSimpleEventPlugin,
215
+ DiscreteEvent,
216
+ );
217
+ registerSimplePluginEventsAndSetTheirPriorities(
218
+ userBlockingPairsForSimpleEventPlugin,
219
+ UserBlockingEvent,
220
+ );
221
+ registerSimplePluginEventsAndSetTheirPriorities(
222
+ continuousPairsForSimpleEventPlugin,
223
+ ContinuousEvent,
224
+ );
225
+ setEventPriorities(otherDiscreteEvents, DiscreteEvent);
226
+}
packages/react-dom/src/events/DOMModernPluginEventSystem.js
+6
-9
@@ -24,10 +24,7 @@ import type {
24
import type {EventPriority, ReactScopeInstance} from 'shared/ReactTypes';
25
import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
26
27
-import {
28
- injectEventPlugin,
29
- registrationNameDependencies,
30
-} from './EventPluginRegistry';
27
+import {registrationNameDependencies} from './EventRegistry';
28
import {
29
PLUGIN_EVENT_SYSTEM,
30
LEGACY_FB_SUPPORT,
@@ -118,11 +115,11 @@ import * as ModernSelectEventPlugin from './plugins/ModernSelectEventPlugin';
115
import * as ModernSimpleEventPlugin from './plugins/ModernSimpleEventPlugin';
116
117
// TODO: remove top-level side effect.
121
-injectEventPlugin(ModernSimpleEventPlugin.eventTypes);
122
-injectEventPlugin(ModernEnterLeaveEventPlugin.eventTypes);
123
-injectEventPlugin(ModernChangeEventPlugin.eventTypes);
124
-injectEventPlugin(ModernSelectEventPlugin.eventTypes);
125
-injectEventPlugin(ModernBeforeInputEventPlugin.eventTypes);
118
+ModernSimpleEventPlugin.registerEvents();
119
+ModernEnterLeaveEventPlugin.registerEvents();
120
+ModernChangeEventPlugin.registerEvents();
121
+ModernSelectEventPlugin.registerEvents();
122
+ModernBeforeInputEventPlugin.registerEvents();
123
124
function extractEvents(
125
dispatchQueue: DispatchQueue,
packages/react-dom/src/events/EventRegistry.js
renamed
+9
-35
@@ -8,7 +8,6 @@
8
*/
9
10
import type {TopLevelType} from './TopLevelEventTypes';
11
-import type {EventTypes} from './PluginModuleType';
11
12
/**
13
* Mapping from registration name to event name
@@ -24,41 +23,22 @@ export const registrationNameDependencies = {};
23
export const possibleRegistrationNames = __DEV__ ? {} : (null: any);
24
// Trust the developer to only use possibleRegistrationNames in __DEV__
25
27
-function publishEventForPlugin(
28
- eventTypes: EventTypes,
29
- eventName: string,
30
-): boolean {
31
- const dispatchConfig = eventTypes[eventName];
32
- const phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
33
- if (phasedRegistrationNames) {
34
- for (const phaseName in phasedRegistrationNames) {
35
- if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
36
- const phasedRegistrationName = phasedRegistrationNames[phaseName];
37
- publishRegistrationName(
38
- phasedRegistrationName,
39
- eventTypes[eventName].dependencies,
40
- );
41
- }
42
- }
43
- return true;
44
- } else if (dispatchConfig.registrationName) {
45
- publishRegistrationName(
46
- dispatchConfig.registrationName,
47
- eventTypes[eventName].dependencies,
48
- );
49
- return true;
50
- }
51
- return false;
26
+export function registerTwoPhaseEvent(
27
+ registrationName: string,
28
+ dependencies: ?Array<TopLevelType>,
29
+): void {
30
+ registerDirectEvent(registrationName, dependencies);
31
+ registerDirectEvent(registrationName + 'Capture', dependencies);
32
}
33
54
-function publishRegistrationName(
34
+export function registerDirectEvent(
35
registrationName: string,
36
dependencies: ?Array<TopLevelType>,
57
-): void {
37
+) {
38
if (__DEV__) {
39
if (registrationNameDependencies[registrationName]) {
40
console.error(
61
- 'EventPluginRegistry: More than one plugin attempted to publish the same ' +
41
+ 'EventRegistry: More than one plugin attempted to publish the same ' +
42
'registration name, `%s`.',
43
registrationName,
44
);
@@ -76,9 +56,3 @@ function publishRegistrationName(
56
}
57
}
58
}
79
-
80
-export function injectEventPlugin(eventTypes: EventTypes): void {
81
- for (const eventName in eventTypes) {
82
- publishEventForPlugin(eventTypes, eventName);
83
- }
84
-}
packages/react-dom/src/events/PluginModuleType.js
+1
-6
@@ -8,12 +8,7 @@
8
*/
9
10
import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
11
-import type {
12
- DispatchConfig,
13
- ReactSyntheticEvent,
14
-} from './ReactSyntheticEventType';
15
-
16
-export type EventTypes = {[key: string]: DispatchConfig, ...};
11
+import type {ReactSyntheticEvent} from './ReactSyntheticEventType';
12
13
export type AnyNativeEvent = Event | KeyboardEvent | MouseEvent | TouchEvent;
14
packages/react-dom/src/events/plugins/ModernBeforeInputEventPlugin.js
+34
-58
@@ -9,6 +9,7 @@ import type {TopLevelType} from '../../events/TopLevelEventTypes';
9
10
import {canUseDOM} from 'shared/ExecutionEnvironment';
11
12
+import {registerTwoPhaseEvent} from '../EventRegistry';
13
import {
14
TOP_BLUR,
15
TOP_COMPOSITION_START,
@@ -57,63 +58,38 @@ const useFallbackCompositionData =
58
const SPACEBAR_CODE = 32;
59
const SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
60
60
-// Events and their corresponding property names.
61
-const eventTypes: EventTypes = {
62
- beforeInput: {
63
- phasedRegistrationNames: {
64
- bubbled: 'onBeforeInput',
65
- captured: 'onBeforeInputCapture',
66
- },
67
- dependencies: [
68
- TOP_COMPOSITION_END,
69
- TOP_KEY_PRESS,
70
- TOP_TEXT_INPUT,
71
- TOP_PASTE,
72
- ],
73
- },
74
- compositionEnd: {
75
- phasedRegistrationNames: {
76
- bubbled: 'onCompositionEnd',
77
- captured: 'onCompositionEndCapture',
78
- },
79
- dependencies: [
80
- TOP_BLUR,
81
- TOP_COMPOSITION_END,
82
- TOP_KEY_DOWN,
83
- TOP_KEY_PRESS,
84
- TOP_KEY_UP,
85
- TOP_MOUSE_DOWN,
86
- ],
87
- },
88
- compositionStart: {
89
- phasedRegistrationNames: {
90
- bubbled: 'onCompositionStart',
91
- captured: 'onCompositionStartCapture',
92
- },
93
- dependencies: [
94
- TOP_BLUR,
95
- TOP_COMPOSITION_START,
96
- TOP_KEY_DOWN,
97
- TOP_KEY_PRESS,
98
- TOP_KEY_UP,
99
- TOP_MOUSE_DOWN,
100
- ],
101
- },
102
- compositionUpdate: {
103
- phasedRegistrationNames: {
104
- bubbled: 'onCompositionUpdate',
105
- captured: 'onCompositionUpdateCapture',
106
- },
107
- dependencies: [
108
- TOP_BLUR,
109
- TOP_COMPOSITION_UPDATE,
110
- TOP_KEY_DOWN,
111
- TOP_KEY_PRESS,
112
- TOP_KEY_UP,
113
- TOP_MOUSE_DOWN,
114
- ],
115
- },
116
-};
61
+function registerEvents() {
62
+ registerTwoPhaseEvent('onBeforeInput', [
63
+ TOP_COMPOSITION_END,
64
+ TOP_KEY_PRESS,
65
+ TOP_TEXT_INPUT,
66
+ TOP_PASTE,
67
+ ]);
68
+ registerTwoPhaseEvent('onCompositionEnd', [
69
+ TOP_BLUR,
70
+ TOP_COMPOSITION_END,
71
+ TOP_KEY_DOWN,
72
+ TOP_KEY_PRESS,
73
+ TOP_KEY_UP,
74
+ TOP_MOUSE_DOWN,
75
+ ]);
76
+ registerTwoPhaseEvent('onCompositionStart', [
77
+ TOP_BLUR,
78
+ TOP_COMPOSITION_START,
79
+ TOP_KEY_DOWN,
80
+ TOP_KEY_PRESS,
81
+ TOP_KEY_UP,
82
+ TOP_MOUSE_DOWN,
83
+ ]);
84
+ registerTwoPhaseEvent('onCompositionUpdate', [
85
+ TOP_BLUR,
86
+ TOP_COMPOSITION_UPDATE,
87
+ TOP_KEY_DOWN,
88
+ TOP_KEY_PRESS,
89
+ TOP_KEY_UP,
90
+ TOP_MOUSE_DOWN,
91
+ ]);
92
+}
93
94
// Track whether we've ever handled a keypress on the space key.
95
let hasSpaceKeypress = false;
@@ -482,4 +458,4 @@ function extractEvents(
458
);
459
}
460
485
-export {eventTypes, extractEvents};
461
+export {registerEvents, extractEvents};
packages/react-dom/src/events/plugins/ModernChangeEventPlugin.js
+15
-20
@@ -6,11 +6,12 @@
6
*
7
* @flow
8
*/
9
-import type {AnyNativeEvent, EventTypes} from '../PluginModuleType';
9
+import type {AnyNativeEvent} from '../PluginModuleType';
10
import type {TopLevelType} from '../TopLevelEventTypes';
11
import type {DispatchQueue} from '../PluginModuleType';
12
import type {EventSystemFlags} from '../EventSystemFlags';
13
14
+import {registerTwoPhaseEvent} from '../EventRegistry';
15
import SyntheticEvent from '../SyntheticEvent';
16
import isTextInputElement from '../isTextInputElement';
17
import {canUseDOM} from 'shared/ExecutionEnvironment';
@@ -39,24 +40,18 @@ import {
40
accumulateTwoPhaseListeners,
41
} from '../DOMModernPluginEventSystem';
42
42
-const eventTypes: EventTypes = {
43
- change: {
44
- phasedRegistrationNames: {
45
- bubbled: 'onChange',
46
- captured: 'onChangeCapture',
47
- },
48
- dependencies: [
49
- TOP_BLUR,
50
- TOP_CHANGE,
51
- TOP_CLICK,
52
- TOP_FOCUS,
53
- TOP_INPUT,
54
- TOP_KEY_DOWN,
55
- TOP_KEY_UP,
56
- TOP_SELECTION_CHANGE,
57
- ],
58
- },
59
-};
43
+function registerEvents() {
44
+ registerTwoPhaseEvent('onChange', [
45
+ TOP_BLUR,
46
+ TOP_CHANGE,
47
+ TOP_CLICK,
48
+ TOP_FOCUS,
49
+ TOP_INPUT,
50
+ TOP_KEY_DOWN,
51
+ TOP_KEY_UP,
52
+ TOP_SELECTION_CHANGE,
53
+ ]);
54
+}
55
56
function createAndAccumulateChangeEvent(
57
dispatchQueue,
@@ -314,4 +309,4 @@ function extractEvents(
309
}
310
}
311
317
-export {eventTypes, extractEvents};
312
+export {registerEvents, extractEvents};
packages/react-dom/src/events/plugins/ModernEnterLeaveEventPlugin.js
+8
-19
@@ -5,6 +5,7 @@
5
* LICENSE file in the root directory of this source tree.
6
*/
7
8
+import {registerDirectEvent} from '../EventRegistry';
9
import {
10
TOP_MOUSE_OUT,
11
TOP_MOUSE_OVER,
@@ -23,24 +24,12 @@ import {accumulateEnterLeaveListeners} from '../DOMModernPluginEventSystem';
24
import {HostComponent, HostText} from 'react-reconciler/src/ReactWorkTags';
25
import {getNearestMountedFiber} from 'react-reconciler/src/ReactFiberTreeReflection';
26
26
-const eventTypes: EventTypes = {
27
- mouseEnter: {
28
- registrationName: 'onMouseEnter',
29
- dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER],
30
- },
31
- mouseLeave: {
32
- registrationName: 'onMouseLeave',
33
- dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER],
34
- },
35
- pointerEnter: {
36
- registrationName: 'onPointerEnter',
37
- dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER],
38
- },
39
- pointerLeave: {
40
- registrationName: 'onPointerLeave',
41
- dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER],
42
- },
43
-};
27
+function registerEvents() {
28
+ registerDirectEvent('onMouseEnter', [TOP_MOUSE_OUT, TOP_MOUSE_OVER]);
29
+ registerDirectEvent('onMouseLeave', [TOP_MOUSE_OUT, TOP_MOUSE_OVER]);
30
+ registerDirectEvent('onPointerEnter', [TOP_POINTER_OUT, TOP_POINTER_OVER]);
31
+ registerDirectEvent('onPointerLeave', [TOP_POINTER_OUT, TOP_POINTER_OVER]);
32
+}
33
34
/**
35
* For almost every interaction we care about, there will be both a top-level
@@ -173,4 +162,4 @@ function extractEvents(
162
accumulateEnterLeaveListeners(dispatchQueue, leave, enter, from, to);
163
}
164
176
-export {eventTypes, extractEvents};
165
+export {registerEvents, extractEvents};
packages/react-dom/src/events/plugins/ModernSelectEventPlugin.js
+22
-24
@@ -10,6 +10,7 @@ import SyntheticEvent from '../../events/SyntheticEvent';
10
import isTextInputElement from '../isTextInputElement';
11
import shallowEqual from 'shared/shallowEqual';
12
13
+import {registerTwoPhaseEvent} from '../EventRegistry';
14
import {
15
TOP_BLUR,
16
TOP_CONTEXT_MENU,
@@ -48,15 +49,12 @@ const rootTargetDependencies = [
49
TOP_MOUSE_UP,
50
];
51
51
-const eventTypes: EventTypes = {
52
- select: {
53
- phasedRegistrationNames: {
54
- bubbled: 'onSelect',
55
- captured: 'onSelectCapture',
56
- },
57
- dependencies: [...rootTargetDependencies, TOP_SELECTION_CHANGE],
58
- },
59
-};
52
+function registerEvents() {
53
+ registerTwoPhaseEvent('onSelect', [
54
+ ...rootTargetDependencies,
55
+ TOP_SELECTION_CHANGE,
56
+ ]);
57
+}
58
59
let activeElement = null;
60
let activeElementInst = null;
@@ -176,6 +174,20 @@ function isListeningToEvent(
174
return listenerMap.has(listenerMapKey);
175
}
176
177
+/**
178
+ * This plugin creates an `onSelect` event that normalizes select events
179
+ * across form elements.
180
+ *
181
+ * Supported elements are:
182
+ * - input (see `isTextInputElement`)
183
+ * - textarea
184
+ * - contentEditable
185
+ *
186
+ * This differs from native browser implementations in the following ways:
187
+ * - Fires on contentEditable fields as well as inputs.
188
+ * - Fires for collapsed selection.
189
+ * - Fires after user input.
190
+ */
191
function extractEvents(
192
dispatchQueue,
193
topLevelType,
@@ -254,18 +266,4 @@ function extractEvents(
266
return;
267
}
268
257
-/**
258
- * This plugin creates an `onSelect` event that normalizes select events
259
- * across form elements.
260
- *
261
- * Supported elements are:
262
- * - input (see `isTextInputElement`)
263
- * - textarea
264
- * - contentEditable
265
- *
266
- * This differs from native browser implementations in the following ways:
267
- * - Fires on contentEditable fields as well as inputs.
268
- * - Fires for collapsed selection.
269
- * - Fires after user input.
270
- */
271
-export {eventTypes, extractEvents};
269
+export {registerEvents, extractEvents};
packages/react-dom/src/events/plugins/ModernSimpleEventPlugin.js
+2
-7
@@ -20,7 +20,7 @@ import SyntheticEvent from '../../events/SyntheticEvent';
20
import * as DOMTopLevelEventTypes from '../DOMTopLevelEventTypes';
21
import {
22
topLevelEventsToReactNames,
23
- simpleEventPluginEventTypes,
23
+ registerSimpleEvents,
24
} from '../DOMEventProperties';
25
import {
26
accumulateTwoPhaseListeners,
@@ -165,9 +165,4 @@ function extractEvents(
165
return event;
166
}
167
168
-export {
169
- // simpleEventPluginEventTypes gets populated from
170
- // the DOMEventProperties module.
171
- simpleEventPluginEventTypes as eventTypes,
172
- extractEvents,
173
-};
168
+export {registerSimpleEvents as registerEvents, extractEvents};