Further cleanup of plugin event system (#18056)
Dominic Gannaway committed
Feb 18, 2020 at 13:31 UTC
f48a5e64e8fd903293f5b854beb795dcc6bae86d
9 files changed
+221
-227
packages/react-dom/src/__tests__/ReactBrowserEventEmitter-test.internal.js
+14
-10
@@ -14,7 +14,8 @@ let EventPluginRegistry;
14
let React;
15
let ReactDOM;
16
let ReactDOMComponentTree;
17
-let ReactBrowserEventEmitter;
17
+let DOMEventPluginSystem;
18
+let ReactDOMEventListener;
19
let ReactTestUtils;
20
21
let idCallOrder;
@@ -52,18 +53,21 @@ function registerSimpleTestHandler() {
53
return getListener(CHILD, ON_CLICK_KEY);
54
}
55
56
+// We should probably remove this file at some point, it's just full of
57
+// internal API usage. ReactBrowserEventEmitter was refactored out in
58
+// #18056 too. The majority of this code lives in DOMEventPluginSystem.
59
describe('ReactBrowserEventEmitter', () => {
60
beforeEach(() => {
61
jest.resetModules();
62
LISTENER.mockClear();
63
60
- // TODO: can we express this test with only public API?
64
EventPluginGetListener = require('legacy-events/getListener').default;
65
EventPluginRegistry = require('legacy-events/EventPluginRegistry');
66
React = require('react');
67
ReactDOM = require('react-dom');
68
ReactDOMComponentTree = require('../client/ReactDOMComponentTree');
66
- ReactBrowserEventEmitter = require('../events/ReactBrowserEventEmitter');
69
+ DOMEventPluginSystem = require('../events/DOMEventPluginSystem');
70
+ ReactDOMEventListener = require('../events/ReactDOMEventListener');
71
ReactTestUtils = require('react-dom/test-utils');
72
73
container = document.createElement('div');
@@ -177,12 +181,12 @@ describe('ReactBrowserEventEmitter', () => {
181
expect(LISTENER).toHaveBeenCalledTimes(1);
182
});
183
180
- it('should not invoke handlers if ReactBrowserEventEmitter is disabled', () => {
184
+ it('should not invoke handlers if ReactDOMEventListener is disabled', () => {
185
registerSimpleTestHandler();
182
- ReactBrowserEventEmitter.setEnabled(false);
186
+ ReactDOMEventListener.setEnabled(false);
187
CHILD.click();
188
expect(LISTENER).toHaveBeenCalledTimes(0);
185
- ReactBrowserEventEmitter.setEnabled(true);
189
+ ReactDOMEventListener.setEnabled(true);
190
CHILD.click();
191
expect(LISTENER).toHaveBeenCalledTimes(1);
192
});
@@ -346,15 +350,15 @@ describe('ReactBrowserEventEmitter', () => {
350
351
it('should listen to events only once', () => {
352
spyOnDevAndProd(EventTarget.prototype, 'addEventListener');
349
- ReactBrowserEventEmitter.listenTo(ON_CLICK_KEY, document);
350
- ReactBrowserEventEmitter.listenTo(ON_CLICK_KEY, document);
353
+ DOMEventPluginSystem.listenToEvent(ON_CLICK_KEY, document);
354
+ DOMEventPluginSystem.listenToEvent(ON_CLICK_KEY, document);
355
expect(EventTarget.prototype.addEventListener).toHaveBeenCalledTimes(1);
356
});
357
358
it('should work with event plugins without dependencies', () => {
359
spyOnDevAndProd(EventTarget.prototype, 'addEventListener');
360
357
- ReactBrowserEventEmitter.listenTo(ON_CLICK_KEY, document);
361
+ DOMEventPluginSystem.listenToEvent(ON_CLICK_KEY, document);
362
363
expect(EventTarget.prototype.addEventListener.calls.argsFor(0)[0]).toBe(
364
'click',
@@ -364,7 +368,7 @@ describe('ReactBrowserEventEmitter', () => {
368
it('should work with event plugins with dependencies', () => {
369
spyOnDevAndProd(EventTarget.prototype, 'addEventListener');
370
367
- ReactBrowserEventEmitter.listenTo(ON_CHANGE_KEY, document);
371
+ DOMEventPluginSystem.listenToEvent(ON_CHANGE_KEY, document);
372
373
const setEventListeners = [];
374
const listenCalls = EventTarget.prototype.addEventListener.calls.allArgs();
packages/react-dom/src/client/ReactDOMComponent.js
+4
-6
@@ -57,14 +57,11 @@ import {
57
TOP_SUBMIT,
58
TOP_TOGGLE,
59
} from '../events/DOMTopLevelEventTypes';
60
-import {
61
- listenTo,
62
- trapBubbledEvent,
63
- getListenerMapForElement,
64
-} from '../events/ReactBrowserEventEmitter';
60
+import {getListenerMapForElement} from '../events/DOMEventListenerMap';
61
import {
62
addResponderEventSystemEvent,
63
removeActiveResponderEventSystemEvent,
64
+ trapBubbledEvent,
65
} from '../events/ReactDOMEventListener.js';
66
import {mediaEventTypes} from '../events/DOMTopLevelEventTypes';
67
import {
@@ -90,6 +87,7 @@ import {
87
enableDeprecatedFlareAPI,
88
enableTrustedTypesIntegration,
89
} from 'shared/ReactFeatureFlags';
90
+import {listenToEvent} from '../events/DOMEventPluginSystem';
91
92
let didWarnInvalidHydration = false;
93
let didWarnShadyDOM = false;
@@ -274,7 +272,7 @@ function ensureListeningTo(
272
const doc = isDocumentOrFragment
273
? rootContainerElement
274
: rootContainerElement.ownerDocument;
277
- listenTo(registrationName, doc);
275
+ listenToEvent(registrationName, doc);
276
}
277
278
function getOwnerDocumentFromRootContainer(
packages/react-dom/src/client/ReactDOMFB.js
+1
-1
@@ -10,7 +10,7 @@
10
import {addUserTimingListener} from 'shared/ReactFeatureFlags';
11
12
import ReactDOM from './ReactDOM';
13
-import {isEnabled} from '../events/ReactBrowserEventEmitter';
13
+import {isEnabled} from '../events/ReactDOMEventListener';
14
import {getClosestInstanceFromNode} from './ReactDOMComponentTree';
15
16
if (__EXPERIMENTAL__) {
packages/react-dom/src/client/ReactDOMHostConfig.js
+1
-1
@@ -34,7 +34,7 @@ import {validateDOMNesting, updatedAncestorInfo} from './validateDOMNesting';
34
import {
35
isEnabled as ReactBrowserEventEmitterIsEnabled,
36
setEnabled as ReactBrowserEventEmitterSetEnabled,
37
-} from '../events/ReactBrowserEventEmitter';
37
+} from '../events/ReactDOMEventListener';
38
import {getChildNamespace} from '../shared/DOMNamespaces';
39
import {
40
ELEMENT_NODE,
packages/react-dom/src/events/DOMEventListenerMap.js
new
+31
@@ -0,0 +1,31 @@
1
+/**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow
8
+ */
9
+
10
+import type {DOMTopLevelEventType} from 'legacy-events/TopLevelEventTypes';
11
+
12
+const PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
13
+// prettier-ignore
14
+const elementListenerMap:
15
+ // $FlowFixMe Work around Flow bug
16
+ | WeakMap
17
+ | Map<
18
+ Document | Element | Node,
19
+ Map<DOMTopLevelEventType | string, null | (any => void)>,
20
+ > = new PossiblyWeakMap();
21
+
22
+export function getListenerMapForElement(
23
+ element: Document | Element | Node,
24
+): Map<DOMTopLevelEventType | string, null | (any => void)> {
25
+ let listenerMap = elementListenerMap.get(element);
26
+ if (listenerMap === undefined) {
27
+ listenerMap = new Map();
28
+ elementListenerMap.set(element, listenerMap);
29
+ }
30
+ return listenerMap;
31
+}
packages/react-dom/src/events/DOMEventPluginSystem.js
+166
@@ -21,9 +21,81 @@ import {batchedEventUpdates} from 'legacy-events/ReactGenericBatching';
21
import {runEventsInBatch} from 'legacy-events/EventBatching';
22
import {plugins} from 'legacy-events/EventPluginRegistry';
23
import accumulateInto from 'legacy-events/accumulateInto';
24
+import {registrationNameDependencies} from 'legacy-events/EventPluginRegistry';
25
26
import getEventTarget from './getEventTarget';
27
import {getClosestInstanceFromNode} from '../client/ReactDOMComponentTree';
28
+import {trapCapturedEvent, trapBubbledEvent} from './ReactDOMEventListener';
29
+import {getListenerMapForElement} from './DOMEventListenerMap';
30
+import isEventSupported from './isEventSupported';
31
+import {
32
+ TOP_BLUR,
33
+ TOP_CANCEL,
34
+ TOP_CLOSE,
35
+ TOP_FOCUS,
36
+ TOP_INVALID,
37
+ TOP_RESET,
38
+ TOP_SCROLL,
39
+ TOP_SUBMIT,
40
+ getRawEventName,
41
+ mediaEventTypes,
42
+} from './DOMTopLevelEventTypes';
43
+
44
+/**
45
+ * Summary of `DOMEventPluginSystem` event handling:
46
+ *
47
+ * - Top-level delegation is used to trap most native browser events. This
48
+ * may only occur in the main thread and is the responsibility of
49
+ * ReactDOMEventListener, which is injected and can therefore support
50
+ * pluggable event sources. This is the only work that occurs in the main
51
+ * thread.
52
+ *
53
+ * - We normalize and de-duplicate events to account for browser quirks. This
54
+ * may be done in the worker thread.
55
+ *
56
+ * - Forward these native events (with the associated top-level type used to
57
+ * trap it) to `EventPluginRegistry`, which in turn will ask plugins if they want
58
+ * to extract any synthetic events.
59
+ *
60
+ * - The `EventPluginRegistry` will then process each event by annotating them with
61
+ * "dispatches", a sequence of listeners and IDs that care about that event.
62
+ *
63
+ * - The `EventPluginRegistry` then dispatches the events.
64
+ *
65
+ * Overview of React and the event system:
66
+ *
67
+ * +------------+ .
68
+ * | DOM | .
69
+ * +------------+ .
70
+ * | .
71
+ * v .
72
+ * +------------+ .
73
+ * | ReactEvent | .
74
+ * | Listener | .
75
+ * +------------+ . +-----------+
76
+ * | . +--------+|SimpleEvent|
77
+ * | . | |Plugin |
78
+ * +-----|------+ . v +-----------+
79
+ * | | | . +--------------+ +------------+
80
+ * | +-----------.--->|PluginRegistry| | Event |
81
+ * | | . | | +-----------+ | Propagators|
82
+ * | ReactEvent | . | | |TapEvent | |------------|
83
+ * | Emitter | . | |<---+|Plugin | |other plugin|
84
+ * | | . | | +-----------+ | utilities |
85
+ * | +-----------.--->| | +------------+
86
+ * | | | . +--------------+
87
+ * +-----|------+ . ^ +-----------+
88
+ * | . | |Enter/Leave|
89
+ * + . +-------+|Plugin |
90
+ * +-------------+ . +-----------+
91
+ * | application | .
92
+ * |-------------| .
93
+ * | | .
94
+ * | | .
95
+ * +-------------+ .
96
+ * .
97
+ * React Core . General Purpose Event Plugin System
98
+ */
99
100
const CALLBACK_BOOKKEEPING_POOL_SIZE = 10;
101
const callbackBookkeepingPool = [];
@@ -213,3 +285,97 @@ export function dispatchEventForPluginEventSystem(
285
releaseTopLevelCallbackBookKeeping(bookKeeping);
286
}
287
}
288
+
289
+/**
290
+ * We listen for bubbled touch events on the document object.
291
+ *
292
+ * Firefox v8.01 (and possibly others) exhibited strange behavior when
293
+ * mounting `onmousemove` events at some node that was not the document
294
+ * element. The symptoms were that if your mouse is not moving over something
295
+ * contained within that mount point (for example on the background) the
296
+ * top-level listeners for `onmousemove` won't be called. However, if you
297
+ * register the `mousemove` on the document object, then it will of course
298
+ * catch all `mousemove`s. This along with iOS quirks, justifies restricting
299
+ * top-level listeners to the document object only, at least for these
300
+ * movement types of events and possibly all events.
301
+ *
302
+ * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
303
+ *
304
+ * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
305
+ * they bubble to document.
306
+ *
307
+ * @param {string} registrationName Name of listener (e.g. `onClick`).
308
+ * @param {object} mountAt Container where to mount the listener
309
+ */
310
+export function listenToEvent(
311
+ registrationName: string,
312
+ mountAt: Document | Element | Node,
313
+): void {
314
+ const listeningSet = getListenerMapForElement(mountAt);
315
+ const dependencies = registrationNameDependencies[registrationName];
316
+
317
+ for (let i = 0; i < dependencies.length; i++) {
318
+ const dependency = dependencies[i];
319
+ listenToTopLevelEvent(dependency, mountAt, listeningSet);
320
+ }
321
+}
322
+
323
+export function listenToTopLevelEvent(
324
+ topLevelType: DOMTopLevelEventType,
325
+ mountAt: Document | Element | Node,
326
+ listenerMap: Map<DOMTopLevelEventType | string, null | (any => void)>,
327
+): void {
328
+ if (!listenerMap.has(topLevelType)) {
329
+ switch (topLevelType) {
330
+ case TOP_SCROLL:
331
+ trapCapturedEvent(TOP_SCROLL, mountAt);
332
+ break;
333
+ case TOP_FOCUS:
334
+ case TOP_BLUR:
335
+ trapCapturedEvent(TOP_FOCUS, mountAt);
336
+ trapCapturedEvent(TOP_BLUR, mountAt);
337
+ // We set the flag for a single dependency later in this function,
338
+ // but this ensures we mark both as attached rather than just one.
339
+ listenerMap.set(TOP_BLUR, null);
340
+ listenerMap.set(TOP_FOCUS, null);
341
+ break;
342
+ case TOP_CANCEL:
343
+ case TOP_CLOSE:
344
+ if (isEventSupported(getRawEventName(topLevelType))) {
345
+ trapCapturedEvent(topLevelType, mountAt);
346
+ }
347
+ break;
348
+ case TOP_INVALID:
349
+ case TOP_SUBMIT:
350
+ case TOP_RESET:
351
+ // We listen to them on the target DOM elements.
352
+ // Some of them bubble so we don't want them to fire twice.
353
+ break;
354
+ default:
355
+ // By default, listen on the top level to all non-media events.
356
+ // Media events don't bubble so adding the listener wouldn't do anything.
357
+ const isMediaEvent = mediaEventTypes.indexOf(topLevelType) !== -1;
358
+ if (!isMediaEvent) {
359
+ trapBubbledEvent(topLevelType, mountAt);
360
+ }
361
+ break;
362
+ }
363
+ listenerMap.set(topLevelType, null);
364
+ }
365
+}
366
+
367
+export function isListeningToAllDependencies(
368
+ registrationName: string,
369
+ mountAt: Document | Element,
370
+): boolean {
371
+ const listenerMap = getListenerMapForElement(mountAt);
372
+ const dependencies = registrationNameDependencies[registrationName];
373
+
374
+ for (let i = 0; i < dependencies.length; i++) {
375
+ const dependency = dependencies[i];
376
+ if (!listenerMap.has(dependency)) {
377
+ return false;
378
+ }
379
+ }
380
+ return true;
381
+}
packages/react-dom/src/events/ReactBrowserEventEmitter.js
deleted
-203
@@ -1,203 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- */
9
-
10
-import {registrationNameDependencies} from 'legacy-events/EventPluginRegistry';
11
-import type {DOMTopLevelEventType} from 'legacy-events/TopLevelEventTypes';
12
-import {
13
- TOP_BLUR,
14
- TOP_CANCEL,
15
- TOP_CLOSE,
16
- TOP_FOCUS,
17
- TOP_INVALID,
18
- TOP_RESET,
19
- TOP_SCROLL,
20
- TOP_SUBMIT,
21
- getRawEventName,
22
- mediaEventTypes,
23
-} from './DOMTopLevelEventTypes';
24
-import {
25
- setEnabled,
26
- isEnabled,
27
- trapBubbledEvent,
28
- trapCapturedEvent,
29
-} from './ReactDOMEventListener';
30
-import isEventSupported from './isEventSupported';
31
-
32
-/**
33
- * Summary of `ReactBrowserEventEmitter` event handling:
34
- *
35
- * - Top-level delegation is used to trap most native browser events. This
36
- * may only occur in the main thread and is the responsibility of
37
- * ReactDOMEventListener, which is injected and can therefore support
38
- * pluggable event sources. This is the only work that occurs in the main
39
- * thread.
40
- *
41
- * - We normalize and de-duplicate events to account for browser quirks. This
42
- * may be done in the worker thread.
43
- *
44
- * - Forward these native events (with the associated top-level type used to
45
- * trap it) to `EventPluginRegistry`, which in turn will ask plugins if they want
46
- * to extract any synthetic events.
47
- *
48
- * - The `EventPluginRegistry` will then process each event by annotating them with
49
- * "dispatches", a sequence of listeners and IDs that care about that event.
50
- *
51
- * - The `EventPluginRegistry` then dispatches the events.
52
- *
53
- * Overview of React and the event system:
54
- *
55
- * +------------+ .
56
- * | DOM | .
57
- * +------------+ .
58
- * | .
59
- * v .
60
- * +------------+ .
61
- * | ReactEvent | .
62
- * | Listener | .
63
- * +------------+ . +-----------+
64
- * | . +--------+|SimpleEvent|
65
- * | . | |Plugin |
66
- * +-----|------+ . v +-----------+
67
- * | | | . +--------------+ +------------+
68
- * | +-----------.--->|PluginRegistry| | Event |
69
- * | | . | | +-----------+ | Propagators|
70
- * | ReactEvent | . | | |TapEvent | |------------|
71
- * | Emitter | . | |<---+|Plugin | |other plugin|
72
- * | | . | | +-----------+ | utilities |
73
- * | +-----------.--->| | +------------+
74
- * | | | . +--------------+
75
- * +-----|------+ . ^ +-----------+
76
- * | . | |Enter/Leave|
77
- * + . +-------+|Plugin |
78
- * +-------------+ . +-----------+
79
- * | application | .
80
- * |-------------| .
81
- * | | .
82
- * | | .
83
- * +-------------+ .
84
- * .
85
- * React Core . General Purpose Event Plugin System
86
- */
87
-
88
-const PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
89
-// prettier-ignore
90
-const elementListenerMap:
91
- // $FlowFixMe Work around Flow bug
92
- | WeakMap
93
- | Map<
94
- Document | Element | Node,
95
- Map<DOMTopLevelEventType | string, null | (any => void)>,
96
- > = new PossiblyWeakMap();
97
-
98
-export function getListenerMapForElement(
99
- element: Document | Element | Node,
100
-): Map<DOMTopLevelEventType | string, null | (any => void)> {
101
- let listenerMap = elementListenerMap.get(element);
102
- if (listenerMap === undefined) {
103
- listenerMap = new Map();
104
- elementListenerMap.set(element, listenerMap);
105
- }
106
- return listenerMap;
107
-}
108
-
109
-/**
110
- * We listen for bubbled touch events on the document object.
111
- *
112
- * Firefox v8.01 (and possibly others) exhibited strange behavior when
113
- * mounting `onmousemove` events at some node that was not the document
114
- * element. The symptoms were that if your mouse is not moving over something
115
- * contained within that mount point (for example on the background) the
116
- * top-level listeners for `onmousemove` won't be called. However, if you
117
- * register the `mousemove` on the document object, then it will of course
118
- * catch all `mousemove`s. This along with iOS quirks, justifies restricting
119
- * top-level listeners to the document object only, at least for these
120
- * movement types of events and possibly all events.
121
- *
122
- * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
123
- *
124
- * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
125
- * they bubble to document.
126
- *
127
- * @param {string} registrationName Name of listener (e.g. `onClick`).
128
- * @param {object} mountAt Container where to mount the listener
129
- */
130
-export function listenTo(
131
- registrationName: string,
132
- mountAt: Document | Element | Node,
133
-): void {
134
- const listeningSet = getListenerMapForElement(mountAt);
135
- const dependencies = registrationNameDependencies[registrationName];
136
-
137
- for (let i = 0; i < dependencies.length; i++) {
138
- const dependency = dependencies[i];
139
- listenToTopLevel(dependency, mountAt, listeningSet);
140
- }
141
-}
142
-
143
-export function listenToTopLevel(
144
- topLevelType: DOMTopLevelEventType,
145
- mountAt: Document | Element | Node,
146
- listenerMap: Map<DOMTopLevelEventType | string, null | (any => void)>,
147
-): void {
148
- if (!listenerMap.has(topLevelType)) {
149
- switch (topLevelType) {
150
- case TOP_SCROLL:
151
- trapCapturedEvent(TOP_SCROLL, mountAt);
152
- break;
153
- case TOP_FOCUS:
154
- case TOP_BLUR:
155
- trapCapturedEvent(TOP_FOCUS, mountAt);
156
- trapCapturedEvent(TOP_BLUR, mountAt);
157
- // We set the flag for a single dependency later in this function,
158
- // but this ensures we mark both as attached rather than just one.
159
- listenerMap.set(TOP_BLUR, null);
160
- listenerMap.set(TOP_FOCUS, null);
161
- break;
162
- case TOP_CANCEL:
163
- case TOP_CLOSE:
164
- if (isEventSupported(getRawEventName(topLevelType))) {
165
- trapCapturedEvent(topLevelType, mountAt);
166
- }
167
- break;
168
- case TOP_INVALID:
169
- case TOP_SUBMIT:
170
- case TOP_RESET:
171
- // We listen to them on the target DOM elements.
172
- // Some of them bubble so we don't want them to fire twice.
173
- break;
174
- default:
175
- // By default, listen on the top level to all non-media events.
176
- // Media events don't bubble so adding the listener wouldn't do anything.
177
- const isMediaEvent = mediaEventTypes.indexOf(topLevelType) !== -1;
178
- if (!isMediaEvent) {
179
- trapBubbledEvent(topLevelType, mountAt);
180
- }
181
- break;
182
- }
183
- listenerMap.set(topLevelType, null);
184
- }
185
-}
186
-
187
-export function isListeningToAllDependencies(
188
- registrationName: string,
189
- mountAt: Document | Element,
190
-): boolean {
191
- const listenerMap = getListenerMapForElement(mountAt);
192
- const dependencies = registrationNameDependencies[registrationName];
193
-
194
- for (let i = 0; i < dependencies.length; i++) {
195
- const dependency = dependencies[i];
196
- if (!listenerMap.has(dependency)) {
197
- return false;
198
- }
199
- }
200
- return true;
201
-}
202
-
203
-export {setEnabled, isEnabled, trapBubbledEvent, trapCapturedEvent};
packages/react-dom/src/events/ReactDOMEventReplaying.js
+3
-5
@@ -32,10 +32,7 @@ import {
32
attemptToDispatchEvent,
33
addResponderEventSystemEvent,
34
} from './ReactDOMEventListener';
35
-import {
36
- getListenerMapForElement,
37
- listenToTopLevel,
38
-} from './ReactBrowserEventEmitter';
35
+import {getListenerMapForElement} from './DOMEventListenerMap';
36
import {
37
getInstanceFromNode,
38
getClosestInstanceFromNode,
@@ -120,6 +117,7 @@ import {
117
TOP_BLUR,
118
} from './DOMTopLevelEventTypes';
119
import {IS_REPLAYED} from 'legacy-events/EventSystemFlags';
120
+import {listenToTopLevelEvent} from './DOMEventPluginSystem';
121
122
type QueuedReplayableEvent = {|
123
blockedOn: null | Container | SuspenseInstance,
@@ -217,7 +215,7 @@ function trapReplayableEvent(
215
document: Document,
216
listenerMap: Map<DOMTopLevelEventType | string, null | (any => void)>,
217
) {
220
- listenToTopLevel(topLevelType, document, listenerMap);
218
+ listenToTopLevelEvent(topLevelType, document, listenerMap);
219
if (enableDeprecatedFlareAPI) {
220
// Trap events for the responder system.
221
const topLevelTypeString = unsafeCastDOMTopLevelTypeToString(topLevelType);
packages/react-dom/src/events/SelectEventPlugin.js
+1
-1
@@ -22,11 +22,11 @@ import {
22
TOP_MOUSE_UP,
23
TOP_SELECTION_CHANGE,
24
} from './DOMTopLevelEventTypes';
25
-import {isListeningToAllDependencies} from './ReactBrowserEventEmitter';
25
import getActiveElement from '../client/getActiveElement';
26
import {getNodeFromInstance} from '../client/ReactDOMComponentTree';
27
import {hasSelectionCapabilities} from '../client/ReactInputSelection';
28
import {DOCUMENT_NODE} from '../shared/HTMLNodeType';
29
+import {isListeningToAllDependencies} from './DOMEventPluginSystem';
30
31
const skipSelectionChangeEvent =
32
canUseDOM && 'documentMode' in document && document.documentMode <= 11;