Skip to content

Commit 0705b72

Browse files
authored
Refine event system types + pass through priority (#18305)
1 parent 45d26f6 commit 0705b72

File tree

5 files changed

+32
-10
lines changed

5 files changed

+32
-10
lines changed

packages/react-dom/src/client/ReactDOMComponent.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ import {
5959
import {getListenerMapForElement} from '../events/DOMEventListenerMap';
6060
import {
6161
addResponderEventSystemEvent,
62-
removeTrappedPassiveEventListener,
62+
removeTrappedEventListener,
6363
} from '../events/ReactDOMEventListener.js';
6464
import {mediaEventTypes} from '../events/DOMTopLevelEventTypes';
6565
import {
@@ -1360,10 +1360,11 @@ export function listenToEventResponderEventTypes(
13601360
const passiveKey = targetEventType + '_passive';
13611361
const passiveListener = listenerMap.get(passiveKey);
13621362
if (passiveListener != null) {
1363-
removeTrappedPassiveEventListener(
1363+
removeTrappedEventListener(
13641364
document,
13651365
targetEventType,
13661366
passiveListener,
1367+
true,
13671368
);
13681369
}
13691370
}

packages/react-dom/src/events/DOMEventListenerMap.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,14 @@ const elementListenerMap:
1818
| WeakMap
1919
| Map<EventTarget, Map<DOMTopLevelEventType | string, null | (any => void)>> = new PossiblyWeakMap();
2020

21+
export type ElementListenerMap = Map<
22+
DOMTopLevelEventType | string,
23+
null | (any => void),
24+
>;
25+
2126
export function getListenerMapForElement(
2227
target: EventTarget,
23-
): Map<DOMTopLevelEventType | string, null | (any => void)> {
28+
): ElementListenerMap {
2429
let listenerMap = elementListenerMap.get(target);
2530
if (listenerMap === undefined) {
2631
listenerMap = new Map();

packages/react-dom/src/events/DOMModernPluginEventSystem.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99

1010
import type {AnyNativeEvent} from 'legacy-events/PluginModuleType';
1111
import type {DOMTopLevelEventType} from 'legacy-events/TopLevelEventTypes';
12+
import type {ElementListenerMap} from '../events/DOMEventListenerMap';
1213
import type {EventSystemFlags} from 'legacy-events/EventSystemFlags';
14+
import type {EventPriority} from 'shared/ReactTypes';
1315
import type {Fiber} from 'react-reconciler/src/ReactFiber';
1416
import type {PluginModule} from 'legacy-events/PluginModuleType';
1517
import type {ReactSyntheticEvent} from 'legacy-events/ReactSyntheticEventType';
@@ -154,9 +156,13 @@ function dispatchEventsForPlugins(
154156
export function listenToTopLevelEvent(
155157
topLevelType: DOMTopLevelEventType,
156158
targetContainer: EventTarget,
157-
listenerMap: Map<DOMTopLevelEventType | string, null | (any => void)>,
159+
listenerMap: ElementListenerMap,
158160
passive?: boolean,
161+
priority?: EventPriority,
159162
): void {
163+
// TODO: we need to know if the listenerMap previously was passive
164+
// and to check if we need to upgrade to active. This will come in
165+
// a useEvent follow up PR.
160166
if (!listenerMap.has(topLevelType)) {
161167
const isCapturePhase = capturePhaseEvents.has(topLevelType);
162168
const listener = addTrappedEventListener(
@@ -165,6 +171,7 @@ export function listenToTopLevelEvent(
165171
isCapturePhase,
166172
false,
167173
passive,
174+
priority,
168175
);
169176
listenerMap.set(topLevelType, listener);
170177
}
@@ -354,7 +361,7 @@ function getNearestRootOrPortalContainer(instance: Element): Element {
354361

355362
export function attachElementListener(listener: ReactDOMListener): void {
356363
const {event, target} = listener;
357-
const {passive, type} = event;
364+
const {passive, priority, type} = event;
358365
let containerEventTarget = target;
359366
// If we the target is a managed React element, then we need to
360367
// find the nearest root/portal contained to attach the event listener
@@ -376,6 +383,7 @@ export function attachElementListener(listener: ReactDOMListener): void {
376383
containerEventTarget,
377384
listenerMap,
378385
passive,
386+
priority,
379387
);
380388
// Get the internal listeners Set from the target instance.
381389
let listeners = getListenersFromTarget(target);

packages/react-dom/src/events/ReactDOMEventListener.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99

1010
import type {AnyNativeEvent} from 'legacy-events/PluginModuleType';
11+
import type {EventPriority} from 'shared/ReactTypes';
1112
import type {FiberRoot} from 'react-reconciler/src/ReactFiberRoot';
1213
import type {Container, SuspenseInstance} from '../client/ReactDOMHostConfig';
1314
import type {DOMTopLevelEventType} from 'legacy-events/TopLevelEventTypes';
@@ -137,10 +138,15 @@ export function addTrappedEventListener(
137138
capture: boolean,
138139
legacyFBSupport?: boolean,
139140
passive?: boolean,
141+
priority?: EventPriority,
140142
): any => void {
143+
const eventPriority =
144+
priority === undefined
145+
? getEventPriorityForPluginSystem(topLevelType)
146+
: priority;
141147
let listener;
142148
let listenerWrapper;
143-
switch (getEventPriorityForPluginSystem(topLevelType)) {
149+
switch (eventPriority) {
144150
case DiscreteEvent:
145151
listenerWrapper = dispatchDiscreteEvent;
146152
break;
@@ -247,18 +253,19 @@ export function addTrappedEventListener(
247253
return fbListener || listener;
248254
}
249255

250-
export function removeTrappedPassiveEventListener(
256+
export function removeTrappedEventListener(
251257
targetContainer: EventTarget,
252258
topLevelType: string,
253259
listener: any => void,
260+
passive: boolean,
254261
) {
255262
if (listener.remove != null) {
256263
listener.remove();
257264
} else {
258265
if (passiveBrowserEventsSupported) {
259266
targetContainer.removeEventListener(topLevelType, listener, {
260267
capture: true,
261-
passive: true,
268+
passive,
262269
});
263270
} else {
264271
targetContainer.removeEventListener(topLevelType, listener, true);

packages/react-dom/src/events/ReactDOMEventReplaying.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import type {AnyNativeEvent} from 'legacy-events/PluginModuleType';
1111
import type {Container, SuspenseInstance} from '../client/ReactDOMHostConfig';
1212
import type {DOMTopLevelEventType} from 'legacy-events/TopLevelEventTypes';
13+
import type {ElementListenerMap} from '../events/DOMEventListenerMap';
1314
import type {EventSystemFlags} from 'legacy-events/EventSystemFlags';
1415
import type {FiberRoot} from 'react-reconciler/src/ReactFiberRoot';
1516

@@ -216,15 +217,15 @@ export function isReplayableDiscreteEvent(
216217
function trapReplayableEventForContainer(
217218
topLevelType: DOMTopLevelEventType,
218219
container: Container,
219-
listenerMap: Map<DOMTopLevelEventType | string, null | (any => void)>,
220+
listenerMap: ElementListenerMap,
220221
) {
221222
listenToTopLevelEvent(topLevelType, ((container: any): Element), listenerMap);
222223
}
223224

224225
function trapReplayableEventForDocument(
225226
topLevelType: DOMTopLevelEventType,
226227
document: Document,
227-
listenerMap: Map<DOMTopLevelEventType | string, null | (any => void)>,
228+
listenerMap: ElementListenerMap,
228229
) {
229230
if (!enableModernEventSystem) {
230231
legacyListenToTopLevelEvent(topLevelType, document, listenerMap);

0 commit comments

Comments
 (0)